Commit the new iPOJO version (0.7.6).

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@642265 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/annotations/pom.xml b/ipojo/annotations/pom.xml
index 9a62990..e2b5446 100644
--- a/ipojo/annotations/pom.xml
+++ b/ipojo/annotations/pom.xml
@@ -19,16 +19,15 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

   <parent>

-    <groupId>org.apache.felix</groupId>

-    <artifactId>felix</artifactId>

-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>

+    <artifactId>iPOJO</artifactId>

+    <groupId>org.apache.felix</groupId>
+    <version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>
   </parent>

   <modelVersion>4.0.0</modelVersion>

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

   <packaging>bundle</packaging>

-  <version>0.7.5-SNAPSHOT</version>

-  <name>iPOJO Annotations</name>

+  <name>Apache Felix iPOJO Annotations</name>

   <build>

   <plugins>

   <plugin>

@@ -38,9 +37,9 @@
 		<source>1.5</source>

 		<target>1.5</target>

 		</configuration>

-	  </plugin>

+	</plugin>

   	<plugin>

-    	<groupId>org.apache.felix</groupId>

+    	<groupId>org.apache.felix</groupId>
     	<artifactId>maven-bundle-plugin</artifactId>

         <version>1.4.0</version>
     	<extensions>true</extensions>

@@ -55,4 +54,15 @@
   	</plugin>

   </plugins>

   </build>

+  <reporting>

+    <plugins>

+      <plugin>

+        <groupId>org.apache.maven.plugins</groupId>

+        <artifactId>maven-checkstyle-plugin</artifactId>

+        <configuration>

+          <configLocation>http://people.apache.org/~clement/styles/checkstyle_ipojo.xml</configLocation>

+        </configuration>

+      </plugin>

+    </plugins>

+  </reporting>

 </project>
\ No newline at end of file
diff --git a/ipojo/ant/pom.xml b/ipojo/ant/pom.xml
index 5ee1876..aae1663 100644
--- a/ipojo/ant/pom.xml
+++ b/ipojo/ant/pom.xml
@@ -1,74 +1,90 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

- <parent>

-    <groupId>org.apache.felix</groupId>

-    <artifactId>felix</artifactId>

-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>

-  </parent>

-  <modelVersion>4.0.0</modelVersion>

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

-  <packaging>bundle</packaging>

-  <version>0.7.5-SNAPSHOT</version>

-  <name>Apache Felix iPOJO Ant Task</name>

-  <dependencies>

-  	<dependency>

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

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

-      <version>0.7.5-SNAPSHOT</version>

-    </dependency>

-    <dependency>

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

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

-      <version>0.7.5-SNAPSHOT</version>

-    </dependency>

-    <dependency>

-      <groupId>xerces</groupId>

-      <artifactId>xercesImpl</artifactId>

-      <version>2.4.0</version>

-    </dependency>

-    <dependency>

-    	<groupId>ant</groupId>

-    	<artifactId>ant</artifactId>

-    	<version>1.6.5</version>

-    </dependency>

-  </dependencies>

-  

-  <build>

-  <plugins>

-  	<plugin>

-    	<groupId>org.apache.felix</groupId>

-    	<artifactId>maven-bundle-plugin</artifactId>

-        <version>1.4.0</version>
-    	<extensions>true</extensions>

-    	<configuration>

-        	<instructions>          

-          		<Bundle-Name>iPOJO Ant Task</Bundle-Name>

-		        <Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>

-        		<Bundle-Description> iPOJO Ant Task </Bundle-Description>

-        		<Private-Package>org.apache.felix.ipojo.metadata, org.apache.felix.ipojo.manipulator, org.apache.felix.ipojo.xml.parser, org.apache.felix.ipojo.manipulation*, org.objectweb.asm;-split-package:=merge-first, org.objectweb.asm.commons;-split-package:=merge-first, org.apache.xerces.parsers, org.apache.xerces.xni*, org.apache.xerces.impl*, org.apache.xerces.util.*</Private-Package>

-          		<Export-Package>org.apache.felix.ipojo.task</Export-Package>

-        	</instructions>

-    	</configuration>

-  	</plugin>

-  </plugins>

-  </build>

+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

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

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Ant Task</name>

+	<dependencies>

+		<dependency>

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

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

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

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

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

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>xerces</groupId>

+			<artifactId>xercesImpl</artifactId>

+			<version>2.4.0</version>

+		</dependency>

+		<dependency>

+			<groupId>ant</groupId>

+			<artifactId>ant</artifactId>

+			<version>1.6.5</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>iPOJO Ant Task</Bundle-Name>

+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>

+						<Bundle-Description>

+							iPOJO Ant Task

+						</Bundle-Description>

+						<Private-Package>

+							org.apache.felix.ipojo.metadata,

+							org.apache.felix.ipojo.manipulator,

+							org.apache.felix.ipojo.xml.parser,

+							org.apache.felix.ipojo.manipulation*,

+							org.objectweb.asm.util;-split-package:=merge-first,

+							org.objectweb.asm;-split-package:=merge-first,

+							org.objectweb.asm.commons;-split-package:=merge-first,

+							org.apache.xerces.parsers,

+							org.apache.xerces.xni*,

+							org.apache.xerces.impl*,

+							org.apache.xerces.util.*

+						</Private-Package>

+						<Export-Package>

+							org.apache.felix.ipojo.task

+						</Export-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

 </project>
\ No newline at end of file
diff --git a/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java b/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
index 242b44a..f210976 100644
--- a/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
+++ b/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
@@ -25,30 +25,21 @@
 import org.apache.tools.ant.Task;

 

 /**

-* iPOJO Ant Task.

-* This Ant taks manipulate an input bundle.

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

-*/

+ * iPOJO Ant Task. This Ant task manipulates an input bundle.

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

+ */

 public class IPojoTask extends Task {

     

-    /**

-     * Metadata file.

-     */

+    /** Metadata file. */

     private File m_metadata;

     

-    /**

-     * Input bundle.

-     */

+    /** Input bundle. */

     private File m_input;

     

-    /**

-     * Output bundle.

-     */

+    /** Output bundle. */

     private File m_output;

 

-    /**

-     * Flag describing if we need to ignore annotation of not.

-     */

+    /** Flag describing if we need to ignore annotation of not. */

     private boolean m_ignoreAnnotations = false;

     

     /**

@@ -96,7 +87,7 @@
             throw new BuildException("The input bundle " + m_input.getAbsolutePath() + " does not exist");

         }

         

-        System.out.println("Input Bundle File : " + m_input.getAbsolutePath());

+        log("Input Bundle File : " + m_input.getAbsolutePath());

         

         // Get metadata file

         if (m_metadata == null) {

@@ -104,25 +95,25 @@
             if (!m_metadata.exists()) {

              // Verify if annotations are ignored

                 if (m_ignoreAnnotations) {

-                    System.out.println("No metadata file found - ignore annotations");

+                    log("No metadata file found & ignore annotations : nothing to do");

                     return;

                 } else {

-                    System.out.println("No metadata file found - try to use only annotations");

+                    log("No metadata file found - try to use only annotations");

                     m_metadata = null;

                 }

             } else {

-                System.out.println("Metadata File : " + m_metadata.getAbsolutePath());

+                log("Metadata File : " + m_metadata.getAbsolutePath());

             }

         } else {

-            // Metadata file is specified, check existency

+            // Metadata file is specified, check existence

             if (!m_metadata.exists()) {

                 throw new BuildException("No metadata file found - the file " + m_metadata.getAbsolutePath() + " does not exist");

             } else {

-                System.out.println("Metadata File : " + m_metadata.getAbsolutePath());

+                log("Metadata File : " + m_metadata.getAbsolutePath());

             }

         }

 

-        System.out.println("Start bundle manipulation");

+        log("Start bundle manipulation");

         

         if (m_output == null) {

             m_output = new File("./_out.jar");

@@ -139,7 +130,7 @@
         }

         pojo.pojoization(m_input, m_output, m_metadata);

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

-            System.out.println((String) pojo.getWarnings().get(i));

+            log((String) pojo.getWarnings().get(i));

         }

         if (pojo.getErrors().size() > 0) { throw new BuildException((String) pojo.getErrors().get(0)); }

         

@@ -152,8 +143,8 @@
             out = m_output.getAbsolutePath();

         }

         

-        System.out.println("Bundle manipulation - SUCCESS");

-        System.out.println("Output File : " + out);

+        log("Bundle manipulation - SUCCESS");

+        log("Output File : " + out);

         

     }

     

diff --git a/ipojo/arch/pom.xml b/ipojo/arch/pom.xml
index f2505e9..bd4b56b 100644
--- a/ipojo/arch/pom.xml
+++ b/ipojo/arch/pom.xml
@@ -1,80 +1,85 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
 -->
 <project>
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix</artifactId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <name>Apache Felix iPOJO Arch Command</name>
-  <version>0.7.5-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>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>${pom.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.shell</artifactId>
-      <version>1.1.0-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-  <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.0</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-          	<Bundle-Name>iPOJO Arch Command</Bundle-Name>
-            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
-            <Private-Package>org.apache.felix.ipojo.arch</Private-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-      <plugin>
-	      <groupId>org.apache.felix</groupId>
-	      <artifactId>maven-ipojo-plugin</artifactId>
-              <version>${pom.version}</version>
-		  <executions>
-          	<execution>
-            	<goals>
-	              <goal>ipojo-bundle</goal>
-               </goals>
-            <configuration>
-   				<ignoreAnnotations>true</ignoreAnnotations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-   </build>
+	<parent>
+		<artifactId>iPOJO</artifactId>
+		<groupId>org.apache.felix</groupId>
+		<version>0.7.6-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<packaging>bundle</packaging>
+	<name>Apache Felix iPOJO Arch Command</name>
+	<artifactId>org.apache.felix.ipojo.arch</artifactId>
+	<dependencies>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo</artifactId>
+			<version>${pom.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>
+			<version>${pom.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.shell</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>1.4.0</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Name>
+							iPOJO Arch Felix Command
+						</Bundle-Name>
+						<Bundle-SymbolicName>
+							${pom.artifactId}
+						</Bundle-SymbolicName>
+						<Private-Package>
+							org.apache.felix.ipojo.arch
+						</Private-Package>
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-ipojo-plugin</artifactId>
+				<version>${pom.version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>ipojo-bundle</goal>
+						</goals>
+						<configuration>
+							<ignoreAnnotations>true</ignoreAnnotations>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
 </project>
diff --git a/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java b/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
index d26522f..26b528d 100644
--- a/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
+++ b/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
@@ -19,7 +19,10 @@
 package org.apache.felix.ipojo.arch;
 
 import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.util.List;
 
+import org.apache.felix.ipojo.IPojoFactory;
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.HandlerFactory;
@@ -29,25 +32,17 @@
 
 /**
  * Implementation of the arch command printing the actual architecture.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ArchCommandImpl implements Command {
 
-    /**
-     * List of arch service.
-     */
+    /** List of arch services. */
     private Architecture[] m_archs;
     
-    /**
-     * Factory services. 
-     */
+    /** Factory services. */
     private Factory[] m_factories;
     
-    
-    /**
-     * Handler Factories.
-     */
+    /** Handler Factories. */
     private Factory[] m_handlers;
 
     /**
@@ -60,7 +55,7 @@
     }
 
     /**
-     * Get help message.
+     * Gets help message.
      * @return the command usage.
      * @see org.apache.felix.shell.Command#getUsage()
      */
@@ -69,7 +64,7 @@
     }
 
     /**
-     * Get a small description.
+     * Gets a small description.
      * @return get a description.
      * @see org.apache.felix.shell.Command#getShortDescription()
      */
@@ -78,7 +73,7 @@
     }
 
     /**
-     * Execute the arch command.
+     * Executes the arch command.
      * @param line : command line
      * @param out : the default output stream
      * @param err : the error output stream
@@ -113,15 +108,41 @@
             printHandlers(out);
             return;
         }
+        
+        if (line2.startsWith("-stats")) {
+            printStats(out);
+            return;
+        }
 
         err.println(getUsage());
     }
     
     /**
-     * Print instance list.
-     * 
-     * @param out :
-     *            default print stream
+     * Prints the statistics.
+     * @param out the out
+     */
+    private void printStats(PrintStream out) {
+        try {
+            Field field = IPojoFactory.class.getDeclaredField("m_instancesName");
+            field.setAccessible(true); // The field is not accessible.
+            List names = (List) field.get(null);
+            out.println("Number of living instances : " + names.size());
+            out.println("Created instances : " + names);
+        } catch (SecurityException e) {
+            out.println("Cannot compute stats : " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            out.println("Cannot compute stats : " + e.getMessage());
+        } catch (IllegalAccessException e) {
+            out.println("Cannot compute stats : " + e.getMessage());
+        } catch (NoSuchFieldException e) {
+            out.println("Cannot compute stats : " + e.getMessage());
+        }
+        
+    }
+
+    /**
+     * Prints instance list.
+     * @param out : default print stream
      */
     private void printInstances(PrintStream out) {
         for (int i = 0; i < m_archs.length; i++) {
@@ -139,7 +160,7 @@
     }
     
     /**
-     * Print instance description.
+     * Prints instance description.
      * @param name : instance name
      * @param out : default print stream
      * @param err : error print stream (if the instance is not found)
@@ -156,7 +177,7 @@
     }
     
     /**
-     * Print Factory information.
+     * Prints factories.
      * @param out : output stream
      */
     private void printFactories(PrintStream out) {
@@ -170,7 +191,7 @@
     }
     
     /**
-     * Print factory description.
+     * Prints factory description.
      * @param name : factory name
      * @param out : default print stream
      * @param err : error print stream (if the factory is not found)
@@ -186,7 +207,7 @@
     }
     
     /**
-     * Print the list of available handlers (and validity).
+     * Prints the list of available handlers (and validity).
      * @param out : default print stream
      */
     private void printHandlers(PrintStream out) {
diff --git a/ipojo/arch/src/main/resources/metadata.xml b/ipojo/arch/src/main/resources/metadata.xml
index f605ec4..d49d553 100644
--- a/ipojo/arch/src/main/resources/metadata.xml
+++ b/ipojo/arch/src/main/resources/metadata.xml
@@ -1,10 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <iPOJO>
-	<Component className="org.apache.felix.ipojo.arch.ArchCommandImpl" factory="false">
-		  <Provides/>
-		  <Requires field="m_archs" optional="true"/>
-		  <Requires field="m_factories" optional="true" filter="(!(handler.name=*))"/>
-		  <Requires field="m_handlers" optional="true" filter="(handler.name=*)"/>
+	<Component className="org.apache.felix.ipojo.arch.ArchCommandImpl"
+		factory="false">
+		<Provides />
+		<Requires field="m_archs" optional="true" />
+		<Requires field="m_factories" optional="true"
+			filter="(!(handler.name=*))" />
+		<Requires field="m_handlers" optional="true"
+			filter="(handler.name=*)" />
 	</Component>
-	<instance component="org.apache.felix.ipojo.arch.ArchCommandImpl" name="ArchCommand"/>
+	<instance component="org.apache.felix.ipojo.arch.ArchCommandImpl"
+		name="ArchCommand" />
 </iPOJO>
\ No newline at end of file
diff --git a/ipojo/composite/pom.xml b/ipojo/composite/pom.xml
new file mode 100644
index 0000000..222dc6d
--- /dev/null
+++ b/ipojo/composite/pom.xml
@@ -0,0 +1,120 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Composite</name>

+	<artifactId>org.apache.felix.ipojo.composite</artifactId>

+	<dependencies>

+		<dependency>

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

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

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

+			<artifactId>org.osgi.compendium</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

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

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

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

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

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

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

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

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

+			<version>${pom.version}</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>iPOJO Composite</Bundle-Name>

+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>

+						<Bundle-Description>

+							iPOJO Composititon Framework

+						</Bundle-Description>

+						<Import-Package>

+							org.apache.felix.ipojo,

+							org.apache.felix.ipojo.architecture,

+							org.apache.felix.ipojo.context,

+							org.apache.felix.ipojo.metadata,

+							org.apache.felix.ipojo.parser,

+							org.apache.felix.ipojo.util,

+							org.osgi.framework

+						</Import-Package>

+						<Private-Package>

+							org.apache.felix.ipojo.manipulation,

+							org.apache.felix.ipojo.composite.architecture,

+							org.apache.felix.ipojo.composite.service*,

+							org.apache.felix.ipojo.composite.instance,

+							org.apache.felix.ipojo.composite.util,

+							!org.objectweb.asm.xml*,

+							org.objectweb.asm*;-split-package:=merge-first

+						</Private-Package>

+						<Export-Package>

+							org.apache.felix.ipojo.composite;

+							version="0.7.6"

+						</Export-Package>

+						<IPOJO-Extension>

+							composite:org.apache.felix.ipojo.composite.CompositeFactory

+						</IPOJO-Extension>

+						<_donotcopy>

+							(CVS|.svn|.+.bak|~.+|metadata.xml)

+						</_donotcopy>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<metadata>metadata.xml</metadata>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
new file mode 100644
index 0000000..9c980a1
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
@@ -0,0 +1,178 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

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

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

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

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

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

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

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

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

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

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.InvalidSyntaxException;

+

+/**

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

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

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

+ * 

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

+ */

+public class CompositeFactory extends ComponentFactory implements TrackerCustomizer {

+

+    /**

+     * Tracker used to track required handler factories.

+     */

+    protected Tracker m_tracker;

+

+    /**

+     * Create a composite factory.

+     * @param context : bundle context

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

+     * @throws ConfigurationException occurs when the element describing the factory is malformed.

+     */

+    public CompositeFactory(BundleContext context, Element metadata) throws ConfigurationException {

+        super(context, metadata);

+    }

+    

+    /**

+     * Check if the metadata are well formed.

+     * @param metadata : metadata

+     * @throws ConfigurationException occurs when the element describing the factory is malformed.

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

+     */

+    public void check(Element metadata) throws ConfigurationException {

+        String name = metadata.getAttribute("name");

+        if (name == null) {

+            throw new ConfigurationException("A composite needs a name : " + metadata);

+        }

+    }

+    

+    public String getClassName() { return "composite"; }

+        

+    

+    /**

+     * Compute required handlers.

+     * @return the list of required handler.

+     */

+    public List getRequiredHandlerList() {

+        List list = new ArrayList();

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

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

+            Element current = elems[i]; 

+            RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());

+            if (! list.contains(req)) { list.add(req); }

+        }

+        

+        // Add architecture if architecture != 'false'

+        String arch = m_componentMetadata.getAttribute("architecture");

+        if (arch == null || arch.equalsIgnoreCase("true")) {

+            RequiredHandler req = new RequiredHandler("architecture", null);

+            if (! list.contains(req)) { list.add(req); }

+        }

+        

+        return list;

+    }

+    

+    /**

+     * Stop all the instance managers.

+     */

+    public synchronized void stopping() {

+        if (m_tracker != null) {

+            m_tracker.close();

+        }

+        m_tracker = null;

+    }

+

+    /**

+     * Start all the instance managers.

+     */

+    public synchronized void starting() {

+        if (m_requiredHandlers.size() != 0) {

+            try {

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

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

+                    + "(factory.state=1)"

+                    + ")";

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

+                m_tracker.open();

+            } catch (InvalidSyntaxException e) {

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

+                stop();

+                return;

+            }

+        }

+    }

+    

+    /**

+     * Create an instance from the current factory.

+     * @param configuration : instance configuration

+     * @param context : bundle context to inject in the instance manager

+     * @param handlers : array of handler object to attached on the instance 

+     * @return the created instance

+     * @throws ConfigurationException either the instance configuration or the instance starting has failed 

+     * @see org.apache.felix.ipojo.ComponentFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])

+     */

+    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {

+        CompositeManager inst = new CompositeManager(this, context, handlers);

+        inst.configure(m_componentMetadata, configuration);

+        inst.start();

+        return inst;

+    }

+

+    /**

+     * Reconfigure an existing instance.

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

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

+     * not consistent with the component type.

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

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

+     */

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

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

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

+        }

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

+        

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

+        

+        if (instance == null) {

+            return; // The instance does not exist.

+        }

+        

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

+    }

+

+    public String getFactoryName() {

+        return m_componentMetadata.getAttribute("name");

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
similarity index 75%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
index bf243e9..4194fed 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeHandler.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
@@ -1,66 +1,83 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo;
-
-
-/**
- * Composite Handler Abstract Class. An composite handler need implements these
- * method to be notified of lifecycle change...
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public abstract class CompositeHandler extends Handler {
-    
-    /**
-     * Composite Handler type.
-     */
-    public static final String HANDLER_TYPE = "composite";
-    
-    /**
-     * Reference on the composite manager.
-     */
-    private CompositeManager m_manager;
-    
-    /**
-     * Set the manager.
-     * This method me be called only once time.
-     * @param cm : the composite manager.
-     */
-    protected final void attach(ComponentInstance cm) {
-        m_manager = (CompositeManager) cm;
-        setLogger(m_manager.getFactory().getLogger());
-    }
-    
-    public final CompositeManager getCompositeManager() {
-        return m_manager;
-    }
-    
-    /**
-     * Get a plugged handler of the same container.
-     * This method must be call only in the start method (or after).
-     * In the configure method, this method can not return a consistent
-     * result as all handlers are not plugged. 
-     * @param name : name of the handler to find (class name). 
-     * @return the composite handler object or null if the handler is not found.
-     */
-    public final Handler getHandler(String name) {
-        return m_manager.getCompositeHandler(name);
-    }
-    
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite;

+

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

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

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

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

+

+

+/**

+ * Composite Handler Abstract Class. An composite handler need implements these

+ * method to be notified of lifecycle change...

+ * 

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

+ */

+public abstract class CompositeHandler extends Handler {

+    

+    /**

+     * Composite Handler type.

+     */

+    public static final String HANDLER_TYPE = "composite";

+    

+    /**

+     * Reference on the composite manager.

+     */

+    private CompositeManager m_manager;

+    

+    /**

+     * Composite Factory.

+     */

+    private CompositeFactory m_factory;

+    

+    /**

+     * Set the manager.

+     * This method me be called only once time.

+     * @param instance : the composite manager.

+     */

+    protected final void attach(ComponentInstance instance) {

+        m_manager = (CompositeManager) instance;

+    }

+    

+    public final void setFactory(Factory factory) {

+        m_factory = (CompositeFactory) factory;

+    }

+    

+    public final Logger getLogger() {

+        return m_factory.getLogger();

+    }

+    

+    public final CompositeManager getCompositeManager() {

+        return m_manager;

+    }

+    

+    /**

+     * Get a plugged handler of the same container.

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

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

+     * result as all handlers are not plugged. 

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

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

+     */

+    public final Handler getHandler(String name) {

+        return m_manager.getCompositeHandler(name);

+    }

+    

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java
similarity index 81%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java
index 69eb78f..00537ea 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeManager.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java
@@ -1,435 +1,442 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.ipojo.composite.CompositeServiceContext;
-import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * iPOJO Composite manager. The composite manager class manages one instance of
- * a component type which is a composition. It manages component lifecycle, and
- * handlers...
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositeManager implements ComponentInstance, InstanceStateListener {
-
-    /**
-     * The context of the component.
-     */
-    private BundleContext m_context;
-
-    /**
-     * Parent factory (ComponentFactory).
-     */
-    private ComponentFactory m_factory;
-
-    /**
-     * Composite Handler list.
-     */
-    private HandlerManager[] m_handlers = new HandlerManager[0];
-
-    /**
-     * Instance State Listener List.
-     */
-    private List m_instanceListeners = new ArrayList();
-
-    /**
-     * Internal service context of the composition.
-     */
-    private CompositeServiceContext m_internalContext;
-    
-    /**
-     * Name of the component instance.
-     */
-    private String m_name;
-
-    /**
-     * Component state (STOPPED at the beginning).
-     */
-    private int m_state = STOPPED;
-
-    /**
-     * Construct a new Component Manager.
-     * @param factory : the factory managing the instance manager
-     * @param bc : the bundle context to give to the instance
-     * @param handlers : the handlers to plug
-     */
-    public CompositeManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
-        m_factory = factory;
-        m_context = bc;
-        // Initialize the service context.
-        m_internalContext = new CompositeServiceContext(m_context, this);
-        m_handlers = handlers;
-    }
-
-    /**
-     * Plug the given handler to the current container.
-     * @param h : the handler to plug.
-     */
-    public synchronized void addCompositeHandler(HandlerManager h) {
-        if (m_handlers.length > 0) {
-            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];
-            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);
-            newInstances[m_handlers.length] = h;
-            m_handlers = newInstances;
-        } else {
-            m_handlers = new HandlerManager[] { h };
-        }
-    }
-
-    /**
-     * Add an instance to the created instance list.
-     * @param listener : the instance state listener to add.
-     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
-     */
-    public void addInstanceStateListener(InstanceStateListener listener) {
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.add(listener);
-        }
-    }
-
-    /**
-     * Configure the instance manager. Stop the existing handler, clear the
-     * handler list, change the metadata, recreate the handler
-     * 
-     * @param cm : the component type metadata
-     * @param configuration : the configuration of the instance
-     * @throws ConfigurationException : occurs when the component type are incorrect.
-     */
-    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {        
-        // Add the name
-        m_name = (String) configuration.get("name");
-        
-        // Create the standard handlers and add these handlers to the list
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].init(this, cm, configuration);
-        }
-    }
-    
-    /** 
-     * Dispose the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
-     */
-    public void dispose() {
-        if (m_state > STOPPED) { stop(); }
-        
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-        }
-        
-        m_factory.disposed(this);
-
-        // Cleaning
-        m_state = DISPOSED;
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].dispose();
-        }
-        m_handlers = new HandlerManager[0];
-        m_instanceListeners.clear();
-    }
-
-    /**
-     * Return a specified handler.
-     * @param name : class name of the handler to find
-     * @return : the handler, or null if not found
-     */
-    public CompositeHandler getCompositeHandler(String name) {
-        for (int i = 0; i < m_handlers.length; i++) {
-            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();
-            if (fact.getHandlerName().equals(name) || fact.getComponentClassName().equals(name)) {
-                return (CompositeHandler) m_handlers[i].getHandler();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the bundle context used by this instance.
-     * @return the parent context of the instance.
-     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
-     */
-    public BundleContext getContext() {
-        return m_context;
-    }
-
-    /**
-     * Get the factory which create this instance.
-     * @return the factory of the component
-     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
-     */
-    public ComponentFactory getFactory() {
-        return m_factory;
-    }
-    
-    /**
-     * Get the global bundle context.
-     * @return the global bundle context.
-     */
-    public BundleContext getGlobalContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getGlobalContext();
-    }
-    
-    /**
-     * Return the instance description of this instance.
-     * @return the instance description.
-     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
-     */
-    public InstanceDescription getInstanceDescription() {
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, m_state, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
-        CompositeHandler[] handlers = getRegistredCompositeHandlers();
-        for (int i = 0; i < handlers.length; i++) {
-            instanceDescription.addHandler(handlers[i].getDescription());
-        }
-
-        // Get instances description of internal instance
-        ServiceReference[] refs;
-        try {
-            refs = m_internalContext.getServiceReferences(Architecture.class.getName(), null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    Architecture arch = (Architecture) m_internalContext.getService(refs[i]);
-                    instanceDescription.addInstance(arch.getInstanceDescription());
-                    m_internalContext.ungetService(refs[i]);
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace(); // Should not happen
-        }
-        return instanceDescription;
-    }
-
-    /**
-     * Get the instance name.
-     * @return the instance name
-     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
-     */
-    public String getInstanceName() {
-        return m_name;
-    }
-
-    /**
-     * Get the parent service context.
-     * @return the parent service context.
-     */
-    public ServiceContext getParentServiceContext() {
-        IPojoContext c = (IPojoContext) m_context;
-        return c.getServiceContext();
-    }
-
-    /**
-     * REturn the list of handlers plugged on this instance.
-     * @return the list of the registered handlers.
-     */
-    public CompositeHandler[] getRegistredCompositeHandlers() {
-        CompositeHandler[] h = new CompositeHandler[m_handlers.length];
-        for (int i = 0; i < m_handlers.length; i++) {
-            h[i] = (CompositeHandler) m_handlers[i].getHandler();
-        }
-        return h;
-    }
-    
-    /**
-     * Get the internal service context of this instance.
-     * @return the internal service context.
-     */
-    public ServiceContext getServiceContext() {
-        return m_internalContext;
-    }
-    
-    /**
-     * Get the actual state of the instance.
-     * @return the actual state of the instance
-     * @see org.apache.felix.ipojo.ComponentInstance#getState()
-     */
-    public int getState() {
-        return m_state;
-    }
-    
-    /**
-     * Check if the instance is started.
-     * @return true if the instance is started.
-     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
-     */
-    public boolean isStarted() {
-        return m_state > STOPPED;
-    }
-
-    /**
-     * Reconfigure the current instance.
-     * @param configuration : the new instance configuration.
-     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
-     */
-    public void reconfigure(Dictionary configuration) {
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].reconfigure(configuration);
-        }
-    }
-
-    /**
-     * Remove an instance state listener.
-     * @param listener : the listener to remove
-     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
-     */
-    public void removeInstanceStateListener(InstanceStateListener listener) {
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.remove(listener);
-        }
-    }
-
-    /**
-     * Set the state of the component. 
-     * if the state changed call the stateChanged(int) method on the handlers.
-     * @param state : new state
-     */
-    public void setState(int state) {
-        if (m_state != state) {
-            if (state > m_state) {
-                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
-                m_state = state;
-                for (int i = 0; i < m_handlers.length; i++) {
-                    m_handlers[i].getHandler().stateChanged(state);
-                }
-            } else {
-                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
-                m_state = state;
-                for (int i = m_handlers.length - 1; i > -1; i--) {
-                    m_handlers[i].getHandler().stateChanged(state);
-                }
-            }
-            
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
-            }
-        }
-    }
-
-    /**
-     * Start the instance manager.
-     */
-    public synchronized void start() {
-        if (m_state > STOPPED) {
-            return;
-        } // Instance already started
-
-
-        // The new state of the component is UNRESOLVED
-        m_state = INVALID;
-
-        m_internalContext.start(); // Turn on the factory tracking
-
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].start();
-            m_handlers[i].addInstanceStateListener(this);
-        }
-        
-        for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i].getState() != VALID) {
-                setState(INVALID);
-                return;
-            }
-        }
-        setState(VALID);
-        
-    }
-
-    /**
-     * State Change listener callback.
-     * This method is notified at each time a plugged handler becomes invalid.
-     * @param instance : changing instance 
-     * @param newState : new state
-     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
-     */
-    public synchronized void stateChanged(ComponentInstance instance, int newState) {
-        if (m_state <= STOPPED) { return; }
-     
-        // Update the component state if necessary
-        if (newState == INVALID && m_state == VALID) {
-            // Need to update the state to UNRESOLVED
-            setState(INVALID);
-            return;
-        }
-        if (newState == VALID && m_state == INVALID) {
-            // An handler becomes valid => check if all handlers are valid
-            boolean isValid = true;
-            for (int i = 0; i < m_handlers.length; i++) {
-                isValid = isValid && m_handlers[i].getState() == VALID;
-            }
-            
-            if (isValid) { setState(VALID); }
-        }
-        if (newState == DISPOSED) {
-            kill();
-        }
-    }
-
-    /**
-     * Stop the instance manager.
-     */
-    public synchronized void stop() {
-        if (m_state <= STOPPED) {
-            return;
-        } // Instance already stopped
-
-        setState(INVALID);
-        // Stop all the handlers
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].removeInstanceStateListener(this);
-            m_handlers[i].stop();
-        }
-
-        m_internalContext.stop(); // Turn off the factory tracking
-        m_state = STOPPED;
-        
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
-        }
-    }
-    
-    /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
-     */
-    protected synchronized void kill() {
-        if (m_state > STOPPED) { stop(); }
-        
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-        }
-
-        // Cleaning
-        m_state = DISPOSED;
-        
-        for (int i = m_handlers.length - 1; i > -1; i--) {
-            m_handlers[i].dispose();
-        }
-        m_handlers = new HandlerManager[0];
-        m_instanceListeners.clear();
-    }
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

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

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

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

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

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

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

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

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * iPOJO Composite manager. The composite manager class manages one instance of

+ * a component type which is a composition. It manages component lifecycle, and

+ * handlers...

+ * 

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

+ */

+public class CompositeManager implements ComponentInstance, InstanceStateListener {

+

+    /**

+     * The context of the component.

+     */

+    private BundleContext m_context;

+

+    /**

+     * Parent factory (ComponentFactory).

+     */

+    private CompositeFactory m_factory;

+

+    /**

+     * Composite Handler list.

+     */

+    private HandlerManager[] m_handlers = new HandlerManager[0];

+

+    /**

+     * Instance State Listener List.

+     */

+    private List m_listeners = new ArrayList();

+

+    /**

+     * Internal service context of the composition.

+     */

+    private CompositeServiceContext m_internalContext;

+    

+    /**

+     * Name of the component instance.

+     */

+    private String m_name;

+

+    /**

+     * Component state (STOPPED at the beginning).

+     */

+    private int m_state = STOPPED;

+

+    /**

+     * Construct a new Component Manager.

+     * @param factory : the factory managing the instance manager

+     * @param context : the bundle context to give to the instance

+     * @param handlers : the handlers to plug

+     */

+    public CompositeManager(CompositeFactory factory, BundleContext context, HandlerManager[] handlers) {

+        m_factory = factory;

+        m_context = context;

+        // Initialize the service context.

+        m_internalContext = new CompositeServiceContext(m_context, this);

+        m_handlers = handlers;

+    }

+

+    /**

+     * Plug the given handler to the current container.

+     * @param handler : the handler to plug.

+     */

+    public synchronized void addCompositeHandler(HandlerManager handler) {

+        if (m_handlers.length > 0) {

+            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];

+            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);

+            newInstances[m_handlers.length] = handler;

+            m_handlers = newInstances;

+        } else {

+            m_handlers = new HandlerManager[] { handler };

+        }

+    }

+

+    /**

+     * Add an instance to the created instance list.

+     * @param listener : the instance state listener to add.

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

+     */

+    public void addInstanceStateListener(InstanceStateListener listener) {

+        synchronized (m_listeners) {

+            m_listeners.add(listener);

+        }

+    }

+

+    /**

+     * Configure the instance manager. Stop the existing handler, clear the

+     * handler list, change the metadata, recreate the handler

+     * 

+     * @param metadata : the component type metadata

+     * @param configuration : the configuration of the instance

+     * @throws ConfigurationException : occurs when the component type are incorrect.

+     */

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

+        // Add the name

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

+        

+        // Create the standard handlers and add these handlers to the list

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

+            m_handlers[i].init(this, metadata, configuration);

+        }

+    }

+    

+    /** 

+     * Dispose the instance.

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

+     */

+    public void dispose() {

+        if (m_state > STOPPED) { stop(); }

+        

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

+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);

+        }

+        

+        m_factory.disposed(this);

+

+        // Cleaning

+        m_state = DISPOSED;

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

+            m_handlers[i].dispose();

+        }

+        m_handlers = new HandlerManager[0];

+        m_listeners.clear();

+    }

+

+    /**

+     * Return a specified handler.

+     * @param name : class name of the handler to find

+     * @return : the handler, or null if not found

+     */

+    public CompositeHandler getCompositeHandler(String name) {

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

+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();

+            if (fact.getHandlerName().equals(name) || fact.getComponentDescription().getClassName().equals(name)) {

+                return (CompositeHandler) m_handlers[i].getHandler();

+            }

+        }

+        return null;

+    }

+

+    /**

+     * Get the bundle context used by this instance.

+     * @return the parent context of the instance.

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

+     */

+    public BundleContext getContext() {

+        return m_context;

+    }

+

+    /**

+     * Get the factory which create this instance.

+     * @return the factory of the component

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

+     */

+    public ComponentFactory getFactory() {

+        return m_factory;

+    }

+    

+    /**

+     * Get the global bundle context.

+     * @return the global bundle context.

+     */

+    public BundleContext getGlobalContext() {

+        IPojoContext context = (IPojoContext) m_context;

+        return context.getGlobalContext();

+    }

+    

+    /**

+     * Return the instance description of this instance.

+     * @return the instance description.

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

+     */

+    public InstanceDescription getInstanceDescription() {

+        InstanceDescription desc = new InstanceDescription(m_name, m_state, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());

+        CompositeHandler[] handlers = getRegistredCompositeHandlers();

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

+            desc.addHandler(handlers[i].getDescription());

+        }

+

+        // Get instances description of internal instance

+        ServiceReference[] refs;

+        try {

+            refs = m_internalContext.getServiceReferences(Architecture.class.getName(), null);

+            if (refs != null) {

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

+                    Architecture arch = (Architecture) m_internalContext.getService(refs[i]);

+                    desc.addInstance(arch.getInstanceDescription());

+                    m_internalContext.ungetService(refs[i]);

+                }

+            }

+        } catch (InvalidSyntaxException e) {

+            // Cannot happen

+        }

+        return desc;

+    }

+

+    /**

+     * Get the instance name.

+     * @return the instance name

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

+     */

+    public String getInstanceName() {

+        return m_name;

+    }

+

+    /**

+     * Get the parent service context.

+     * @return the parent service context.

+     */

+    public ServiceContext getParentServiceContext() {

+        IPojoContext context = (IPojoContext) m_context;

+        return context.getServiceContext();

+    }

+

+    /**

+     * REturn the list of handlers plugged on this instance.

+     * @return the list of the registered handlers.

+     */

+    public CompositeHandler[] getRegistredCompositeHandlers() {

+        CompositeHandler[] handler = new CompositeHandler[m_handlers.length];

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

+            handler[i] = (CompositeHandler) m_handlers[i].getHandler();

+        }

+        return handler;

+    }

+    

+    /**

+     * Get the internal service context of this instance.

+     * @return the internal service context.

+     */

+    public ServiceContext getServiceContext() {

+        return m_internalContext;

+    }

+    

+    /**

+     * Get the actual state of the instance.

+     * @return the actual state of the instance

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

+     */

+    public int getState() {

+        return m_state;

+    }

+    

+    /**

+     * Check if the instance is started.

+     * @return true if the instance is started.

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

+     */

+    public boolean isStarted() {

+        return m_state > STOPPED;

+    }

+

+    /**

+     * Reconfigure the current instance.

+     * @param configuration : the new instance configuration.

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

+     */

+    public void reconfigure(Dictionary configuration) {

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

+            m_handlers[i].reconfigure(configuration);

+        }

+    }

+

+    /**

+     * Remove an instance state listener.

+     * @param listener : the listener to remove

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

+     */

+    public void removeInstanceStateListener(InstanceStateListener listener) {

+        synchronized (m_listeners) {

+            m_listeners.remove(listener);

+        }

+    }

+

+    /**

+     * Set the state of the component. 

+     * if the state changed call the stateChanged(int) method on the handlers.

+     * @param state : new state

+     */

+    public void setState(int state) {

+        if (m_state != state) {

+            if (state > m_state) {

+                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower

+                m_state = state;

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

+                    m_handlers[i].getHandler().stateChanged(state);

+                }

+            } else {

+                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)

+                m_state = state;

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

+                    m_handlers[i].getHandler().stateChanged(state);

+                }

+            }

+            

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

+                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);

+            }

+        }

+    }

+

+    /**

+     * Start the instance manager.

+     */

+    public synchronized void start() {

+        if (m_state > STOPPED) {

+            return;

+        } // Instance already started

+

+

+        // The new state of the component is UNRESOLVED

+        m_state = INVALID;

+

+        m_internalContext.start(); // Turn on the factory tracking

+

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

+            m_handlers[i].start();

+            m_handlers[i].addInstanceStateListener(this);

+        }

+        

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

+            if (m_handlers[i].getState() != VALID) {

+                setState(INVALID);

+                return;

+            }

+        }

+        setState(VALID);

+        

+    }

+

+    /**

+     * State Change listener callback.

+     * This method is notified at each time a plugged handler becomes invalid.

+     * @param instance : changing instance 

+     * @param newState : new state

+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)

+     */

+    public synchronized void stateChanged(ComponentInstance instance, int newState) {

+        if (m_state <= STOPPED) { return; }

+     

+        // Update the component state if necessary

+        if (newState == INVALID && m_state == VALID) {

+            // Need to update the state to UNRESOLVED

+            setState(INVALID);

+            return;

+        }

+        if (newState == VALID && m_state == INVALID) {

+            // An handler becomes valid => check if all handlers are valid

+            boolean isValid = true;

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

+                isValid = isValid && m_handlers[i].getState() == VALID;

+            }

+            

+            if (isValid) { setState(VALID); }

+        }

+        if (newState == DISPOSED) {

+            kill();

+        }

+    }

+

+    /**

+     * Stop the instance manager.

+     */

+    public synchronized void stop() {

+        if (m_state <= STOPPED) {

+            return;

+        } // Instance already stopped

+

+        setState(INVALID);

+        // Stop all the handlers

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

+            m_handlers[i].removeInstanceStateListener(this);

+            m_handlers[i].stop();

+        }

+

+        m_internalContext.stop(); // Turn off the factory tracking

+        m_state = STOPPED;

+        

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

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

+        }

+    }

+    

+    /**

+     * Kill the current instance.

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

+     */

+    protected synchronized void kill() {

+        if (m_state > STOPPED) { stop(); }

+        

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

+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);

+        }

+

+        // Cleaning

+        m_state = DISPOSED;

+        

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

+            m_handlers[i].dispose();

+        }

+        m_handlers = new HandlerManager[0];

+        m_listeners.clear();

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
similarity index 95%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
index d3449d6..1b0ebfc 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
@@ -1,488 +1,482 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.IPojoContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * CompositeServiceContext Class. This class provides an implementation of the
- * service context for composite.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {
-
-    /**
-     * Structure storing the reference, the factory and the registration.
-     */
-    private class Record {
-        /**
-         * Reference of the represented factory from the external context.
-         */
-        private ServiceReference m_ref;
-        /**
-         * Registration of the factory in the internal context.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Represented Factory. 
-         */
-        private FactoryProxy m_fact;
-    }
-
-    /**
-     * List of imported factories.
-     */
-    private List m_factories = new ArrayList();
-
-    /**
-     * External context.
-     */
-    private BundleContext m_parent;
-
-    /**
-     * Internal service registry.
-     */
-    private ServiceRegistry m_registry;
-
-    /**
-     * Component Instance who creates this registry.
-     */
-    private ComponentInstance m_instance;
-    
-    /**
-     * Global service context.
-     */
-    private BundleContext m_global;
-    
-    /**
-     * Tracker tracking Factories to import.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Constructor. This constructor instantiate a service registry with the
-     * given bundle context.
-     * 
-     * @param bc : the bundle context
-     */
-    public CompositeServiceContext(BundleContext bc) {
-        m_registry = new ServiceRegistry(bc);
-        m_parent = bc;
-        if (m_parent instanceof IPojoContext) {
-            m_global = ((IPojoContext) m_parent).getGlobalContext();
-        } else {
-            m_global = m_parent; // the parent context is the global context
-        }
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param bc : the bundle context
-     * @param ci : the component instance owning this context
-     */
-    public CompositeServiceContext(BundleContext bc, ComponentInstance ci) {
-        this(bc);
-        m_instance = ci;
-    }
-
-    /**
-     * Add a service listener.
-     * @param arg0 : The service listener to add
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void addServiceListener(ServiceListener arg0) {
-        m_registry.addServiceListener(arg0);
-    }
-
-    /**
-     * Add a filtered service listener.
-     * @param arg0 : the service listener object to add
-     * @param arg1 : the LDAP filter for this listener
-     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener,
-     * java.lang.String)
-     */
-    public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {
-        m_registry.addServiceListener(arg0, arg1);
-    }
-
-    /**
-     * Get all service references.
-     * @param arg0 : The required service interface.
-     * @param arg1 : LDAP filter
-     * @return the list of all service reference matching with the query
-     * @throws InvalidSyntaxException : occurs when the given filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String,
-     * java.lang.String)
-     */
-    public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {
-        return m_registry.getAllServiceReferences(arg0, arg1);
-    }
-
-    /**
-     * Get a service object for the given service reference.
-     * @param arg0 : the service reference
-     * @return the service object or null if the reference is no more valid or if the object is not accessible
-     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
-     */
-    public Object getService(ServiceReference arg0) {
-        return m_registry.getService(m_instance, arg0);
-    }
-
-    
-    /**
-     * Get a service reference for the required interface.
-     * @param arg0 : the required interface name
-     * @return the service reference or null if no available provider
-     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
-     */
-    public ServiceReference getServiceReference(String arg0) {
-        return m_registry.getServiceReference(arg0);
-    }
-
-    /**
-     * Get all accessible service reference for the given query.
-     * @param clazz : required interface
-     * @param filter : LDAP filter
-     * @return the list (array) of service reference matching with the query.
-     * @throws InvalidSyntaxException : occurs when the LDAP filter is malformed
-     * @see org.apache.felix.ipojo.ServiceContext#getServiceReferences(java.lang.String, java.lang.String)
-     */
-    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        return m_registry.getServiceReferences(clazz, filter);
-    }
-
-
-    /**
-     * Register a service inside the composite context.
-     * @param arg0 : list of interfaces to register.
-     * @param arg1 : service object
-     * @param arg2 : properties list
-     * @return the service registration
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {
-        return m_registry.registerService(m_instance, arg0, arg1, arg2);
-    }
-
-    /**
-     * Register a service inside the composite context.
-     * @param arg0 : interface to register.
-     * @param arg1 : service object
-     * @param arg2 : properties list
-     * @return the service registration
-     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
-     */
-    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
-        return m_registry.registerService(m_instance, arg0, arg1, arg2);
-    }
-
-    /**
-     * Remove a service listener.
-     * @param arg0 : the service listener to remove
-     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
-     */
-    public void removeServiceListener(ServiceListener arg0) {
-        m_registry.removeServiceListener(arg0);
-    }
-
-    /**
-     * Unget a service.
-     * @param arg0 the service reference to unget
-     * @return true
-     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
-     */
-    public boolean ungetService(ServiceReference arg0) {
-        return m_registry.ungetService(m_instance, arg0);
-    }
-
-    /**
-     * Import a factory form the parent to the internal registry.
-     * 
-     * @param ref : the reference of the factory to import.
-     */
-    private void importFactory(ServiceReference ref) {        
-        Record rec = new Record();
-        m_factories.add(rec);
-        Dictionary dict = new Properties();
-        for (int j = 0; j < ref.getPropertyKeys().length; j++) {
-            dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));
-        }
-        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);
-        rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
-        rec.m_ref = ref;
-    }
-
-    /**
-     * Remove a factory of the available factory list.
-     * 
-     * @param ref : the reference on the factory to remove.
-     */
-    private void removeFactory(ServiceReference ref) {
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            if (rec.m_ref == ref) {
-                if (rec.m_reg != null) {
-                    rec.m_reg.unregister();
-                    rec.m_fact = null;
-                }
-                m_tracker.ungetService(rec.m_ref);
-                m_factories.remove(rec);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Start the registry management.
-     */
-    public void start() {
-        m_tracker = new Tracker(m_global, Factory.class.getName(), this);
-        m_tracker.open();
-    }
-
-    /**
-     * Stop the registry management.
-     */
-    public synchronized void stop() {
-        m_tracker.close();
-        m_registry.reset();
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            removeFactory(rec.m_ref);
-        }
-        m_tracker = null;
-    }
-
-    /**
-     * Check if the factory list contain the given reference.
-     * 
-     * @param ref : the reference to find.
-     * @return true if the list contains the given reference.
-     */
-    private boolean containsRef(ServiceReference ref) {
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            if (rec.m_ref == ref) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Add a bundle listener.
-     * Delegate on the global bundle context.
-     * @param arg0 : bundle listener to add
-     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
-     */
-    public void addBundleListener(BundleListener arg0) {
-        m_global.addBundleListener(arg0);
-    }
-
-    /**
-     * Add a framework listener.
-     * Delegate on the global bundle context.
-     * @param arg0 : framework listener to add.
-     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
-     */
-    public void addFrameworkListener(FrameworkListener arg0) {
-        m_global.addFrameworkListener(arg0);
-    }
-
-    /**
-     * Create a LDAP filter.
-     * @param arg0 : String-form of the filter
-     * @return the created filter object
-     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
-     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
-     */
-    public Filter createFilter(String arg0) throws InvalidSyntaxException {
-        return m_global.createFilter(arg0);
-    }
-
-    /**
-     * Get the current bundle.
-     * @return the current bundle
-     * @see org.osgi.framework.BundleContext#getBundle()
-     */
-    public Bundle getBundle() {
-        return m_global.getBundle();
-    }
-
-    /**
-     * Get the bundle object with the given id.
-     * @param id : bundle id
-     * @return the bundle object
-     * @see org.osgi.framework.BundleContext#getBundle(long)
-     */
-    public Bundle getBundle(long id) {
-        return m_global.getBundle(id);
-    }
-
-    /**
-     * Get installed bundles.
-     * @return the list of installed bundles
-     * @see org.osgi.framework.BundleContext#getBundles()
-     */
-    public Bundle[] getBundles() {
-        return m_global.getBundles();
-    }
-
-
-    /**
-     * Get a data file.
-     * @param filename : File name.
-     * @return the File object
-     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
-     */
-    public File getDataFile(String filename) {
-        return m_global.getDataFile(filename);
-    }
-
-    /**
-     * Get a property value.
-     * @param key : key of the asked property
-     * @return the property value (object) or null if no property are associated with the given key
-     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
-     */
-    public String getProperty(String key) {
-        return m_global.getProperty(key);
-    }
-
-    /**
-     * Install a bundle.
-     * @param location : URL of the bundle to install
-     * @return the installed bundle
-     * @throws BundleException : if the bundle cannot be installed correctly
-     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
-     */
-    public Bundle installBundle(String location) throws BundleException {
-        return m_global.installBundle(location);
-    }
-
-    /**
-     * Install a bundle.
-     * @param location : URL of the bundle to install
-     * @param input : 
-     * @return the installed bundle
-     * @throws BundleException : if the bundle cannot be installed correctly
-     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
-     */
-    public Bundle installBundle(String location, InputStream input) throws BundleException {
-        return m_global.installBundle(location, input);
-    }
-
-    /**
-     * Remove a bundle listener.
-     * @param listener : the listener to remove
-     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
-     */
-    public void removeBundleListener(BundleListener listener) {
-        m_global.removeBundleListener(listener);
-    }
-
-    /**
-     * Remove a framework listener.
-     * @param listener : the listener to remove
-     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
-     */
-    public void removeFrameworkListener(FrameworkListener listener) {
-        m_global.removeFrameworkListener(listener);
-    }
-
-    /**
-     * A new factory is detected.
-     * @param reference : service reference
-     * @return true if not already imported.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference reference) {
-        if (!containsRef(reference)) {
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     * A matching reference has been added. The import factory can now be imported.
-     * @param reference : the added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        importFactory(reference);
-    }
-
-    /**
-     * An imported factory is modified.
-     * @param reference : modified reference
-     * @param service : factory object.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) {
-        for (int i = 0; i < m_factories.size(); i++) {
-            Record rec = (Record) m_factories.get(i);
-            if (rec.m_ref == reference) {
-                Dictionary dict = new Properties();
-                for (int j = 0; j < reference.getPropertyKeys().length; j++) {
-                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));
-                }
-                rec.m_reg.setProperties(dict);
-                return;
-            }
-        }
-    }
-
-    /**
-     * An imported factory disappears.
-     * @param reference : reference
-     * @param service : factory object.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-        if (containsRef(reference)) {
-            removeFactory(reference);
-        }
-        
-    }
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite;

+

+import java.io.File;

+import java.io.InputStream;

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

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

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

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

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

+import org.apache.felix.ipojo.context.ServiceRegistry;

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

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

+import org.osgi.framework.Bundle;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.BundleException;

+import org.osgi.framework.BundleListener;

+import org.osgi.framework.Filter;

+import org.osgi.framework.FrameworkListener;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceListener;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * CompositeServiceContext Class. This class provides an implementation of the

+ * service context for composite.

+ * 

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

+ */

+public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {

+

+    /**

+     * Structure storing the reference, the factory and the registration.

+     */

+    private class Record {

+        /**

+         * Reference of the represented factory from the external context.

+         */

+        private ServiceReference m_ref;

+        /**

+         * Registration of the factory in the internal context.

+         */

+        private ServiceRegistration m_reg;

+        /**

+         * Represented Factory. 

+         */

+        private FactoryProxy m_fact;

+    }

+

+    /**

+     * List of imported factories.

+     */

+    private List m_factories = new ArrayList();

+    /**

+     * Internal service registry.

+     */

+    private ServiceRegistry m_registry;

+

+    /**

+     * Component Instance who creates this registry.

+     */

+    private ComponentInstance m_instance;

+    

+    /**

+     * Global service context.

+     */

+    private BundleContext m_global;

+    

+    /**

+     * Tracker tracking Factories to import.

+     */

+    private Tracker m_tracker;

+

+    /**

+     * Constructor. This constructor instantiate a service registry with the

+     * given bundle context.

+     * 

+     * @param context : the bundle context

+     */

+    public CompositeServiceContext(BundleContext context) {

+        m_registry = new ServiceRegistry(context);

+        if (context instanceof IPojoContext) {

+            m_global = ((IPojoContext) context).getGlobalContext();

+        } else {

+            m_global = context; // the parent context is the global context

+        }

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param context : the bundle context

+     * @param instance : the component instance owning this context

+     */

+    public CompositeServiceContext(BundleContext context, ComponentInstance instance) {

+        this(context);

+        m_instance = instance;

+    }

+

+    /**

+     * Add a service listener.

+     * @param arg0 : The service listener to add

+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)

+     */

+    public void addServiceListener(ServiceListener arg0) {

+        m_registry.addServiceListener(arg0);

+    }

+

+    /**

+     * Add a filtered service listener.

+     * @param arg0 : the service listener object to add

+     * @param arg1 : the LDAP filter for this listener

+     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed

+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener,

+     * java.lang.String)

+     */

+    public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {

+        m_registry.addServiceListener(arg0, arg1);

+    }

+

+    /**

+     * Get all service references.

+     * @param arg0 : The required service interface.

+     * @param arg1 : LDAP filter

+     * @return the list of all service reference matching with the query

+     * @throws InvalidSyntaxException : occurs when the given filter is malformed

+     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String,

+     * java.lang.String)

+     */

+    public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {

+        return m_registry.getAllServiceReferences(arg0, arg1);

+    }

+

+    /**

+     * Get a service object for the given service reference.

+     * @param arg0 : the service reference

+     * @return the service object or null if the reference is no more valid or if the object is not accessible

+     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)

+     */

+    public Object getService(ServiceReference arg0) {

+        return m_registry.getService(m_instance, arg0);

+    }

+

+    

+    /**

+     * Get a service reference for the required interface.

+     * @param arg0 : the required interface name

+     * @return the service reference or null if no available provider

+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)

+     */

+    public ServiceReference getServiceReference(String arg0) {

+        return m_registry.getServiceReference(arg0);

+    }

+

+    /**

+     * Get all accessible service reference for the given query.

+     * @param clazz : required interface

+     * @param filter : LDAP filter

+     * @return the list (array) of service reference matching with the query.

+     * @throws InvalidSyntaxException : occurs when the LDAP filter is malformed

+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReferences(java.lang.String, java.lang.String)

+     */

+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {

+        return m_registry.getServiceReferences(clazz, filter);

+    }

+

+

+    /**

+     * Register a service inside the composite context.

+     * @param arg0 : list of interfaces to register.

+     * @param arg1 : service object

+     * @param arg2 : properties list

+     * @return the service registration

+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)

+     */

+    public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {

+        return m_registry.registerService(m_instance, arg0, arg1, arg2);

+    }

+

+    /**

+     * Register a service inside the composite context.

+     * @param arg0 : interface to register.

+     * @param arg1 : service object

+     * @param arg2 : properties list

+     * @return the service registration

+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)

+     */

+    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {

+        return m_registry.registerService(m_instance, arg0, arg1, arg2);

+    }

+

+    /**

+     * Remove a service listener.

+     * @param arg0 : the service listener to remove

+     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)

+     */

+    public void removeServiceListener(ServiceListener arg0) {

+        m_registry.removeServiceListener(arg0);

+    }

+

+    /**

+     * Unget a service.

+     * @param arg0 the service reference to unget

+     * @return true

+     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)

+     */

+    public boolean ungetService(ServiceReference arg0) {

+        return m_registry.ungetService(m_instance, arg0);

+    }

+

+    /**

+     * Import a factory form the parent to the internal registry.

+     * 

+     * @param ref : the reference of the factory to import.

+     */

+    private void importFactory(ServiceReference ref) {        

+        Record rec = new Record();

+        m_factories.add(rec);

+        Dictionary dict = new Properties();

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

+            dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));

+        }

+        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);

+        rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);

+        rec.m_ref = ref;

+    }

+

+    /**

+     * Remove a factory of the available factory list.

+     * 

+     * @param ref : the reference on the factory to remove.

+     */

+    private void removeFactory(ServiceReference ref) {

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

+            Record rec = (Record) m_factories.get(i);

+            if (rec.m_ref == ref) {

+                if (rec.m_reg != null) {

+                    rec.m_reg.unregister();

+                    rec.m_fact = null;

+                }

+                m_tracker.ungetService(rec.m_ref);

+                m_factories.remove(rec);

+                return;

+            }

+        }

+    }

+

+    /**

+     * Start the registry management.

+     */

+    public void start() {

+        m_tracker = new Tracker(m_global, Factory.class.getName(), this);

+        m_tracker.open();

+    }

+

+    /**

+     * Stop the registry management.

+     */

+    public synchronized void stop() {

+        m_tracker.close();

+        m_registry.reset();

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

+            Record rec = (Record) m_factories.get(i);

+            removeFactory(rec.m_ref);

+        }

+        m_tracker = null;

+    }

+

+    /**

+     * Check if the factory list contain the given reference.

+     * 

+     * @param ref : the reference to find.

+     * @return true if the list contains the given reference.

+     */

+    private boolean containsRef(ServiceReference ref) {

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

+            Record rec = (Record) m_factories.get(i);

+            if (rec.m_ref == ref) {

+                return true;

+            }

+        }

+        return false;

+    }

+

+    /**

+     * Add a bundle listener.

+     * Delegate on the global bundle context.

+     * @param arg0 : bundle listener to add

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

+     */

+    public void addBundleListener(BundleListener arg0) {

+        m_global.addBundleListener(arg0);

+    }

+

+    /**

+     * Add a framework listener.

+     * Delegate on the global bundle context.

+     * @param arg0 : framework listener to add.

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

+     */

+    public void addFrameworkListener(FrameworkListener arg0) {

+        m_global.addFrameworkListener(arg0);

+    }

+

+    /**

+     * Create a LDAP filter.

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

+     * @return the created filter object

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

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

+     */

+    public Filter createFilter(String arg0) throws InvalidSyntaxException {

+        return m_global.createFilter(arg0);

+    }

+

+    /**

+     * Get the current bundle.

+     * @return the current bundle

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

+     */

+    public Bundle getBundle() {

+        return m_global.getBundle();

+    }

+

+    /**

+     * Get the bundle object with the given id.

+     * @param bundleId : bundle id

+     * @return the bundle object

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

+     */

+    public Bundle getBundle(long bundleId) {

+        return m_global.getBundle(bundleId);

+    }

+

+    /**

+     * Get installed bundles.

+     * @return the list of installed bundles

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

+     */

+    public Bundle[] getBundles() {

+        return m_global.getBundles();

+    }

+

+

+    /**

+     * Get a data file.

+     * @param filename : File name.

+     * @return the File object

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

+     */

+    public File getDataFile(String filename) {

+        return m_global.getDataFile(filename);

+    }

+

+    /**

+     * Get a property value.

+     * @param key : key of the asked property

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

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

+     */

+    public String getProperty(String key) {

+        return m_global.getProperty(key);

+    }

+

+    /**

+     * Install a bundle.

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

+     * @return the installed bundle

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

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

+     */

+    public Bundle installBundle(String location) throws BundleException {

+        return m_global.installBundle(location);

+    }

+

+    /**

+     * Install a bundle.

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

+     * @param input : 

+     * @return the installed bundle

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

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

+     */

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

+        return m_global.installBundle(location, input);

+    }

+

+    /**

+     * Remove a bundle listener.

+     * @param listener : the listener to remove

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

+     */

+    public void removeBundleListener(BundleListener listener) {

+        m_global.removeBundleListener(listener);

+    }

+

+    /**

+     * Remove a framework listener.

+     * @param listener : the listener to remove

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

+     */

+    public void removeFrameworkListener(FrameworkListener listener) {

+        m_global.removeFrameworkListener(listener);

+    }

+

+    /**

+     * A new factory is detected.

+     * @param reference : service reference

+     * @return true if not already imported.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+     */

+    public boolean addingService(ServiceReference reference) {

+        if (!containsRef(reference)) {

+            return true;

+        }

+        return false;

+    }

+    

+    /**

+     * A matching reference has been added. The import factory can now be imported.

+     * @param reference : the added reference.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

+     */

+    public void addedService(ServiceReference reference) {

+        importFactory(reference);

+    }

+

+    /**

+     * An imported factory is modified.

+     * @param reference : modified reference

+     * @param service : factory object.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

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

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

+            Record rec = (Record) m_factories.get(i);

+            if (rec.m_ref == reference) {

+                Dictionary dict = new Properties();

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

+                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));

+                }

+                rec.m_reg.setProperties(dict);

+                return;

+            }

+        }

+    }

+

+    /**

+     * An imported factory disappears.

+     * @param reference : reference

+     * @param service : factory object.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

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

+        if (containsRef(reference)) {

+            removeFactory(reference);

+        }

+        

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
similarity index 84%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
index 73a61e7..a2a67ba 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
@@ -1,177 +1,173 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.FactoryStateListener;
-import org.apache.felix.ipojo.MissingHandlerException;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.UnacceptableConfiguration;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.BundleContext;
-
-/**
- * Bridge representing a Factory inside a composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class FactoryProxy implements Factory {
-
-    /**
-     * Delegated factory.
-     */
-    private Factory m_delegate;
-
-    /**
-     * Destination context.
-     */
-    private ServiceContext m_context;
-
-    /**
-     * Constructor.
-     * @param fact : the targeted factory.
-     * @param s : the service context to target.
-     */
-    public FactoryProxy(Factory fact, ServiceContext s) {
-        m_delegate = fact;
-        m_context = s;
-    }
-
-    /**
-     * Create an instance manager (i.e. component type instance).
-     * @param configuration : the configuration properties for this component.
-     * @return the created instance manager.
-     * @throws UnacceptableConfiguration : when a given configuration is not valid.
-     * @throws MissingHandlerException : occurs when the creation failed due to a missing handler (the factory should be invalid)
-     * @throws ConfigurationException : occurs when the creation failed due to a configuration issue
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
-     */
-    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
-        return m_delegate.createComponentInstance(configuration, m_context);
-    }
-
-    /**
-     * Create an instance manager (i.e. component type instance). This has these
-     * service interaction in the scope given in argument.
-     * @param configuration : the configuration properties for this component.
-     * @param serviceContext : the service context of the component.
-     * @return the created instance manager.
-     * @throws UnacceptableConfiguration : when the given configuration is not valid.
-     * @throws MissingHandlerException : when at least one handler is missing. 
-     * @throws ConfigurationException : when an issue occurs during the oconfiguration of the instance.
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary,
-     * org.apache.felix.ipojo.ServiceContext)
-     */
-    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
-        return m_delegate.createComponentInstance(configuration, serviceContext);
-    }
-
-    /**
-     * Get the component type information containing provided service,
-     * configuration properties ...
-     * @return the component type information.
-     * @see org.apache.felix.ipojo.Factory#getDescription()
-     */
-    public Element getDescription() {
-        return m_delegate.getDescription();
-    }
-
-    /**
-     * Return the factory name.
-     * @return the name of the factory.
-     * @see org.apache.felix.ipojo.Factory#getName()
-     */
-    public String getName() {
-        return m_delegate.getName();
-    }
-
-    /**
-     * Check if the given configuration is acceptable as a configuration of a
-     * component instance.
-     * @param conf : the configuration to test
-     * @return true if the configuration is acceptable
-     * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
-     */
-    public boolean isAcceptable(Dictionary conf) {
-        return m_delegate.isAcceptable(conf);
-    }
-
-    /**
-     * Reconfigure an instance already created. This configuration need to have
-     * the name property to identify the instance.
-     * @param conf : the configuration to reconfigure the instance.
-     * @throws UnacceptableConfiguration : if the given configuration is not
-     * consistent for the targeted instance.
-     * @throws MissingHandlerException : when at least one handler is missing
-     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
-     */
-    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
-        m_delegate.reconfigure(conf);
-    }
-
-    /**
-     * Add a factory listener.
-     * @param l : the listener to add.
-     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
-     */
-    public void addFactoryStateListener(FactoryStateListener l) {
-        m_delegate.addFactoryStateListener(l);
-
-    }
-
-    public List getMissingHandlers() {
-        return m_delegate.getMissingHandlers();
-    }
-
-    public List getRequiredHandlers() {
-        return m_delegate.getRequiredHandlers();
-    }
-
-    /**
-     * Remove a service listener.
-     * @param l : the listener to remove
-     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
-     */
-    public void removeFactoryStateListener(FactoryStateListener l) {
-        m_delegate.removeFactoryStateListener(l);
-
-    }
-
-    public ComponentDescription getComponentDescription() {
-        return m_delegate.getComponentDescription();
-    }
-
-    public String getClassName() {
-        return m_delegate.getClassName();
-    }
-
-    public int getState() {
-        return m_delegate.getState();
-    }
-
-    public BundleContext getBundleContext() {
-        return m_delegate.getBundleContext();
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite;

+

+import java.util.Dictionary;

+import java.util.List;

+

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

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

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

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

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

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

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

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

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

+import org.osgi.framework.BundleContext;

+

+/**

+ * Bridge representing a Factory inside a composition.

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

+ */

+public class FactoryProxy implements Factory {

+

+    /**

+     * Delegated factory.

+     */

+    private Factory m_delegate;

+

+    /**

+     * Destination context.

+     */

+    private ServiceContext m_context;

+

+    /**

+     * Constructor.

+     * @param fact : the targeted factory.

+     * @param svcContext : the service context to target.

+     */

+    public FactoryProxy(Factory fact, ServiceContext svcContext) {

+        m_delegate = fact;

+        m_context = svcContext;

+    }

+

+    /**

+     * Create an instance manager (i.e. component type instance).

+     * @param configuration : the configuration properties for this component.

+     * @return the created instance manager.

+     * @throws UnacceptableConfiguration : when a given configuration is not valid.

+     * @throws MissingHandlerException : occurs when the creation failed due to a missing handler (the factory should be invalid)

+     * @throws ConfigurationException : occurs when the creation failed due to a configuration issue

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

+     */

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

+            ConfigurationException {

+        return m_delegate.createComponentInstance(configuration, m_context);

+    }

+

+    /**

+     * Create an instance manager (i.e. component type instance). This has these service interaction in the scope given in argument.

+     * @param configuration : the configuration properties for this component.

+     * @param serviceContext : the service context of the component.

+     * @return the created instance manager.

+     * @throws UnacceptableConfiguration : when the given configuration is not valid.

+     * @throws MissingHandlerException : when at least one handler is missing.

+     * @throws ConfigurationException : when an issue occurs during the oconfiguration of the instance.

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

+     */

+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration,

+            MissingHandlerException, ConfigurationException {

+        return m_delegate.createComponentInstance(configuration, serviceContext);

+    }

+

+    /**

+     * Get the component type information containing provided service, configuration properties ...

+     * @return the component type information.

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

+     */

+    public Element getDescription() {

+        return m_delegate.getDescription();

+    }

+

+    /**

+     * Return the factory name.

+     * @return the name of the factory.

+     * @see org.apache.felix.ipojo.Factory#getName()

+     */

+    public String getName() {

+        return m_delegate.getName();

+    }

+

+    /**

+     * Check if the given configuration is acceptable as a configuration of a component instance.

+     * @param conf : the configuration to test

+     * @return true if the configuration is acceptable

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

+     */

+    public boolean isAcceptable(Dictionary conf) {

+        return m_delegate.isAcceptable(conf);

+    }

+

+    /**

+     * Reconfigure an instance already created. This configuration need to have the name property to identify the instance.

+     * @param conf : the configuration to reconfigure the instance.

+     * @throws UnacceptableConfiguration : if the given configuration is not consistent for the targeted instance.

+     * @throws MissingHandlerException : when at least one handler is missing

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

+     */

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

+        m_delegate.reconfigure(conf);

+    }

+

+    /**

+     * Add a factory listener.

+     * @param listener : the listener to add.

+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)

+     */

+    public void addFactoryStateListener(FactoryStateListener listener) {

+        m_delegate.addFactoryStateListener(listener);

+

+    }

+

+    public List getMissingHandlers() {

+        return m_delegate.getMissingHandlers();

+    }

+

+    public List getRequiredHandlers() {

+        return m_delegate.getRequiredHandlers();

+    }

+

+    /**

+     * Remove a service listener.

+     * @param listener : the listener to remove

+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)

+     */

+    public void removeFactoryStateListener(FactoryStateListener listener) {

+        m_delegate.removeFactoryStateListener(listener);

+

+    }

+

+    public ComponentTypeDescription getComponentDescription() {

+        return m_delegate.getComponentDescription();

+    }

+

+    public String getClassName() {

+        return m_delegate.getClassName();

+    }

+

+    public int getState() {

+        return m_delegate.getState();

+    }

+

+    public BundleContext getBundleContext() {

+        return m_delegate.getBundleContext();

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
similarity index 91%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
index ff9ab36..e5554b1 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
@@ -1,76 +1,77 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.architecture;
-
-import java.util.Dictionary;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.Architecture;
-import org.apache.felix.ipojo.architecture.InstanceDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Composite Architecture Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ArchitectureHandler extends CompositeHandler implements Architecture {
-
-    /**
-     * Name of the component.
-     */
-    private String m_name;
-
-    /**
-     * Configure the handler.
-     * 
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(Element metadata, Dictionary configuration) {
-        m_name = (String) configuration.get("name");
-    }
-
-    /**
-     * Stop the handler.
-     * @see org.apache.felix.ipojo.Handler#stop()
-     */
-    public void stop() { }
-
-    /**
-     * Start the handler.
-     * @see org.apache.felix.ipojo.Handler#start()
-     */
-    public void start() { 
-        log(Logger.INFO, "Start composite architecture handler with " + m_name + " name");
-    }
-
-    /**
-     * Get the instance description.
-     * @return the instance description
-     * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
-     */
-    public InstanceDescription getInstanceDescription() {
-        return getCompositeManager().getInstanceDescription();
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.architecture;

+

+import java.util.Dictionary;

+

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

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

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

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

+

+/**

+ * Composite Architecture Handler.

+ * 

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

+ */

+public class ArchitectureHandler extends CompositeHandler implements Architecture {

+

+    /**

+     * Name of the component.

+     */

+    private String m_name;

+

+    /**

+     * Configure the handler.

+     * 

+     * @param metadata : the metadata of the component

+     * @param configuration : the instance configuration

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

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

+     */

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

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

+    }

+

+    /**

+     * Stop the handler.

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

+     */

+    public void stop() {

+        // Nothing to do.

+    }

+

+    /**

+     * Start the handler.

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

+     */

+    public void start() { 

+        info("Start composite architecture handler with " + m_name + " name");

+    }

+

+    /**

+     * Get the instance description.

+     * @return the instance description

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

+     */

+    public InstanceDescription getInstanceDescription() {

+        return getCompositeManager().getInstanceDescription();

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
similarity index 81%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
index b4f82b9..3443073 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
@@ -1,406 +1,402 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.instance;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.InstanceManager;
-import org.apache.felix.ipojo.InstanceStateListener;
-import org.apache.felix.ipojo.MissingHandlerException;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.UnacceptableConfiguration;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ParseException;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Composite Instance Handler.
- * This handler allows creating an instance inside a composite.
- * This instance is determine by its type and a configuration.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class InstanceHandler extends CompositeHandler implements InstanceStateListener {
-
-    /**
-     * Internal context.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * Is the handler valid ?
-     * (Lifecycle controller)
-     */
-    private boolean m_isValid = false;
-    
-    /**
-     * Available factories.
-     */
-    private Factory[] m_factories;
-    
-
-    /**
-     * This structure aims to manage a configuration. It stores all necessary
-     * information to create an instance and to track the factory.
-     */
-    class ManagedConfiguration {
-        /**
-         * Configuration of the instance to create.
-         */
-        private Dictionary m_configuration;
-
-        /**
-         * Factory name.
-         */
-        private String m_factoryName;
-
-        /**
-         * Created instance.
-         */
-        private ComponentInstance m_instance;
-        
-        /**
-         * Desired Factory (can be the classname).
-         */
-        private String m_desiredFactory;
-
-        /**
-         * Constructor.
-         * 
-         * @param conf : the configuration to create.
-         */
-        ManagedConfiguration(Dictionary conf) {
-            m_configuration = conf;
-            m_desiredFactory = (String) conf.get("component");
-        }
-
-        /**
-         * Return the managed configuration.
-         * @return the configuration.
-         */
-        Dictionary getConfiguration() {
-            return m_configuration;
-        }
-
-        /**
-         * Return the used factory name.
-         * @return the factory name
-         */
-        String getFactory() {
-            return m_factoryName;
-        }
-        
-        String getNeededFactoryName() {
-            return m_desiredFactory;
-        }
-
-        /**
-         * Return the created instance.
-         * @return the instance (or null if no instance are created).
-         */
-        ComponentInstance getInstance() {
-            return m_instance;
-        }
-
-        /**
-         * Set the factory name.
-         * 
-         * @param name : the factory name.
-         */
-        void setFactory(String name) {
-            m_factoryName = name;
-        }
-
-        /**
-         * Set the instance object.
-         * 
-         * @param instance : the instance
-         */
-        void setInstance(ComponentInstance instance) {
-            m_instance = instance;
-        }
-    }
-
-    /**
-     * Configurations to create and maintains.
-     */
-    private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
-
-    /**
-     * Create an instance using the given factory and the given configuration.
-     * 
-     * @param fact : the factory name to used.
-     * @param config : the configuration.
-     */
-    private void createInstance(Factory fact, ManagedConfiguration config) {
-        Dictionary conf = config.getConfiguration();
-        try {
-            config.setInstance(fact.createComponentInstance(conf, m_scope));
-            config.setFactory(fact.getName());
-            config.getInstance().addInstanceStateListener(this);
-        } catch (UnacceptableConfiguration e) {
-            log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
-        } catch (MissingHandlerException e) {
-            log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
-        } catch (ConfigurationException e) {
-            log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
-        }
-    }
-    
-    /**
-     * A new valid factory appears.
-     * @param f : factory.
-     */
-    public void bindFactory(Factory f) {
-        boolean implicated = false;
-        String factName = f.getName();
-        String className = f.getComponentDescription().getClassName();
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
-                createInstance(f, m_configurations[i]);
-                implicated = true;
-            }
-        }
-        if (implicated && ! m_isValid) {
-            checkValidity();
-        }
-    }
-    
-    /**
-     * An existing factory disappears or becomes invalid.
-     * @param f : factory
-     */
-    public void unbindFactory(Factory f) {
-        boolean implicated = false;
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(f.getName())) {
-                m_configurations[i].setInstance(null);
-                m_configurations[i].setFactory(null);
-                implicated = true;
-            }
-        }
-        if (implicated && m_isValid) {
-            checkValidity();
-        }
-    }
-
-    /**
-     * Stop all created instances.
-     */
-    public synchronized void stop() {
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                m_configurations[i].getInstance().removeInstanceStateListener(this);
-                if (m_configurations[i].getInstance().getState() != ComponentInstance.DISPOSED) {
-                    m_configurations[i].getInstance().dispose();
-                }
-            }
-            m_configurations[i].setInstance(null);
-            m_configurations[i].setFactory(null);
-        }
-        m_configurations = new ManagedConfiguration[0];
-    }
-
-    /**
-     * Configure method.
-     * @param metadata : component type metadata.
-     * @param configuration : instance configuration.
-     * @throws ConfigurationException : occurs an instance cannot be parsed correctly. 
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
-        m_scope = getCompositeManager().getServiceContext();
-        Element[] instances = metadata.getElements("instance");
-        m_configurations = new ManagedConfiguration[instances.length];
-        for (int i = 0; i < instances.length; i++) {
-            Dictionary conf = null;
-            try {
-                conf = parseInstance(instances[i]);
-            } catch (ParseException e) {
-                log(Logger.ERROR, "An instance cannot be parsed correctly", e);
-                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage());
-            }
-            m_configurations[i] = new ManagedConfiguration(conf);
-        }
-    }
-
-    /**
-     * Parse an Element to get a dictionary.
-     * @param instance : the Element describing an instance.
-     * @return : the resulting dictionary
-     * @throws ParseException : occurs when a configuration cannot be parse correctly.
-     */
-    private Dictionary parseInstance(Element instance) throws ParseException {
-        Dictionary dict = new Properties();
-        String name = instance.getAttribute("name");
-        if (name != null) {
-            dict.put("name", name);
-        }
-        
-        String comp = instance.getAttribute("component");
-        if (comp == null) { 
-            throw new ParseException("An instance does not have the 'component' attribute"); 
-        } else {
-            dict.put("component", comp);
-        }
-
-        for (int i = 0; i < instance.getElements("property").length; i++) {
-            parseProperty(instance.getElements("property")[i], dict);
-        }
-
-        return dict;
-    }
-
-    /**
-     * Parse a property.
-     * @param prop : the current element to parse
-     * @param dict : the dictionary to populate
-     * @throws ParseException : occurs if the property cannot be parsed correctly
-     */
-    private void parseProperty(Element prop, Dictionary dict) throws ParseException {
-        // Check that the property has a name
-        String name = prop.getAttribute("name");
-        String value = prop.getAttribute("value");
-        if (name == null) { throw new ParseException("A property does not have the 'name' attribute"); }
-        // Final case : the property element has a 'value' attribute
-        if (value != null) {
-            dict.put(name, value);
-        } else {
-            // Recursive case
-            // Check if there is 'property' element
-            Element[] subProps = prop.getElements("property");
-            if (subProps.length == 0) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }
-            Dictionary dict2 = new Properties();
-            for (int i = 0; i < subProps.length; i++) {
-                parseProperty(subProps[i], dict2);
-                dict.put(prop.getAttribute("name"), dict2);
-            }
-        }
-    }
-
-    /**
-     * Start method.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() { 
-        for (int j = 0; j < m_factories.length; j++) {
-            String factName = m_factories[j].getName();
-            String className = m_factories[j].getClassName(); 
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
-                    createInstance(m_factories[j], m_configurations[i]);
-                }
-            }
-        }
-        
-        checkValidity();
-    }
-
-    /**
-     * Check handler validity.
-     * The method update the m_validity field.
-     * @return the new validity.
-     */
-    private boolean checkValidity() {
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() == null || m_configurations[i].getInstance().getState() != ComponentInstance.VALID) {
-                m_isValid = false;
-                return false;
-            }
-        }
-        m_isValid = true;
-        return true;
-    }
-
-    /**
-     *  Instance state listener.
-     *  This method listens when managed instance states change.
-     *  @param instance : instance
-     *  @param newState : the now state of the given instance
-     *  @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
-     */
-    public void stateChanged(ComponentInstance instance, int newState) {
-        switch (newState) {
-            case ComponentInstance.DISPOSED:
-            case ComponentInstance.STOPPED:
-                break; // Should not happen
-            case ComponentInstance.VALID:
-                if (!m_isValid) {
-                    checkValidity();
-                }
-                break;
-            case ComponentInstance.INVALID:
-                if (m_isValid) {
-                    checkValidity();
-                }
-                break;
-            default:
-                break;
-
-        }
-    }
-
-    /**
-     * Method returning an instance object of the given component type.
-     * This method must be called only on 'primitive' type.
-     * @param type : type.
-     * @return an instance object or null if not found.
-     */
-    public Object getObjectFromInstance(String type) {
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory()) && m_configurations[i].getInstance().getState() == ComponentInstance.VALID) { 
-                return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject(); 
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the handler description, i.e. the state of created instances.
-     * @return the handler description.
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        List l = new ArrayList();
-        for (int i = 0; i < m_configurations.length; i++) {
-            l.add(m_configurations[i]);
-        }
-        return new InstanceHandlerDescription(this, l);
-    }
-
-    /**
-     * Get the list of used component type.
-     * @return the list containing the used component type
-     */
-    public List getUsedType() {
-        List result = new ArrayList();
-        for (int i = 0; i < m_configurations.length; i++) {
-            result.add(m_configurations[i].getConfiguration().get("component"));
-        }
-        return result;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.instance;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

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

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

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

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

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

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

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

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

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

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

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

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

+

+/**

+ * Composite Instance Handler.

+ * This handler allows creating an instance inside a composite.

+ * This instance is determine by its type and a configuration.

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

+ */

+public class InstanceHandler extends CompositeHandler implements InstanceStateListener {

+

+    /**

+     * Internal context.

+     */

+    private ServiceContext m_scope;

+    

+    /**

+     * Available factories.

+     */

+    private Factory[] m_factories;

+    

+

+    /**

+     * This structure aims to manage a configuration. It stores all necessary

+     * information to create an instance and to track the factory.

+     */

+    class ManagedConfiguration {

+        /**

+         * Configuration of the instance to create.

+         */

+        private Dictionary m_configuration;

+

+        /**

+         * Factory name.

+         */

+        private String m_factoryName;

+

+        /**

+         * Created instance.

+         */

+        private ComponentInstance m_instance;

+        

+        /**

+         * Desired Factory (can be the classname).

+         */

+        private String m_desiredFactory;

+

+        /**

+         * Constructor.

+         * 

+         * @param conf : the configuration to create.

+         */

+        ManagedConfiguration(Dictionary conf) {

+            m_configuration = conf;

+            m_desiredFactory = (String) conf.get("component");

+        }

+

+        /**

+         * Return the managed configuration.

+         * @return the configuration.

+         */

+        protected Dictionary getConfiguration() {

+            return m_configuration;

+        }

+

+        /**

+         * Return the used factory name.

+         * @return the factory name

+         */

+        protected String getFactory() {

+            return m_factoryName;

+        }

+        

+        protected String getNeededFactoryName() {

+            return m_desiredFactory;

+        }

+

+        /**

+         * Return the created instance.

+         * @return the instance (or null if no instance are created).

+         */

+        protected ComponentInstance getInstance() {

+            return m_instance;

+        }

+

+        /**

+         * Set the factory name.

+         * 

+         * @param name : the factory name.

+         */

+        protected void setFactory(String name) {

+            m_factoryName = name;

+        }

+

+        /**

+         * Set the instance object.

+         * 

+         * @param instance : the instance

+         */

+        protected void setInstance(ComponentInstance instance) {

+            m_instance = instance;

+        }

+    }

+

+    /**

+     * Configurations to create and maintains.

+     */

+    private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];

+

+    /**

+     * Create an instance using the given factory and the given configuration.

+     * 

+     * @param fact : the factory name to used.

+     * @param config : the configuration.

+     */

+    private void createInstance(Factory fact, ManagedConfiguration config) {

+        Dictionary conf = config.getConfiguration();

+        try {

+            config.setInstance(fact.createComponentInstance(conf, m_scope));

+            config.setFactory(fact.getName());

+            config.getInstance().addInstanceStateListener(this);

+        } catch (UnacceptableConfiguration e) {

+            error("A factory is available for the configuration but the configuration is not acceptable", e);

+        } catch (MissingHandlerException e) {

+            error("The instance creation has failed, at least one handler is missing", e);

+        } catch (ConfigurationException e) {

+            error("The instance creation has failed, an error during the configuration has occured", e);

+        }

+    }

+    

+    /**

+     * A new valid factory appears.

+     * @param factory : factory.

+     */

+    public void bindFactory(Factory factory) {

+        boolean implicated = false;

+        String factName = factory.getName();

+        String className = factory.getComponentDescription().getClassName();

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

+            if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {

+                createInstance(factory, m_configurations[i]);

+                implicated = true;

+            }

+        }

+        if (implicated && ! getValidity()) {

+            checkValidity();

+        }

+    }

+    

+    /**

+     * An existing factory disappears or becomes invalid.

+     * @param factory : factory

+     */

+    public void unbindFactory(Factory factory) {

+        boolean implicated = false;

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

+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {

+                m_configurations[i].setInstance(null);

+                m_configurations[i].setFactory(null);

+                implicated = true;

+            }

+        }

+        if (implicated && getValidity()) {

+            checkValidity();

+        }

+    }

+

+    /**

+     * Stop all created instances.

+     */

+    public synchronized void stop() {

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

+            if (m_configurations[i].getInstance() != null) {

+                m_configurations[i].getInstance().removeInstanceStateListener(this);

+                if (m_configurations[i].getInstance().getState() != ComponentInstance.DISPOSED) {

+                    m_configurations[i].getInstance().dispose();

+                }

+            }

+            m_configurations[i].setInstance(null);

+            m_configurations[i].setFactory(null);

+        }

+        m_configurations = new ManagedConfiguration[0];

+    }

+

+    /**

+     * Configure method.

+     * @param metadata : component type metadata.

+     * @param configuration : instance configuration.

+     * @throws ConfigurationException : occurs an instance cannot be parsed correctly. 

+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

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

+        m_scope = getCompositeManager().getServiceContext();

+        Element[] instances = metadata.getElements("instance");

+        m_configurations = new ManagedConfiguration[instances.length];

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

+            Dictionary conf = null;

+            try {

+                conf = parseInstance(instances[i]);

+            } catch (ParseException e) {

+                error("An instance cannot be parsed correctly", e);

+                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage());

+            }

+            m_configurations[i] = new ManagedConfiguration(conf);

+        }

+    }

+

+    /**

+     * Parse an Element to get a dictionary.

+     * @param instance : the Element describing an instance.

+     * @return : the resulting dictionary

+     * @throws ParseException : occurs when a configuration cannot be parse correctly.

+     */

+    public static Dictionary parseInstance(Element instance) throws ParseException {

+        Dictionary dict = new Properties();

+        String name = instance.getAttribute("name");

+        if (name != null) {

+            dict.put("name", name);

+        }

+        

+        String comp = instance.getAttribute("component");

+        if (comp == null) { 

+            throw new ParseException("An instance does not have the 'component' attribute"); 

+        } else {

+            dict.put("component", comp);

+        }

+

+        Element[] props = instance.getElements("property");

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

+            parseProperty(props[i], dict);

+        }

+

+        return dict;

+    }

+

+    /**

+     * Parse a property.

+     * @param prop : the current element to parse

+     * @param dict : the dictionary to populate

+     * @throws ParseException : occurs if the property cannot be parsed correctly

+     */

+    public static void parseProperty(Element prop, Dictionary dict) throws ParseException {

+        // Check that the property has a name

+        String name = prop.getAttribute("name");

+        String value = prop.getAttribute("value");

+        if (name == null) { throw new ParseException("A property does not have the 'name' attribute"); }

+        // Final case : the property element has a 'value' attribute

+        if (value == null) {

+            // Recursive case

+            // Check if there is 'property' element

+            Element[] subProps = prop.getElements("property");

+            if (subProps == null) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }

+            Dictionary dict2 = new Properties();

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

+                parseProperty(subProps[i], dict2);

+                dict.put(prop.getAttribute("name"), dict2);

+            }

+        } else {

+            dict.put(name, value);

+        }

+    }

+

+    /**

+     * Start method.

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

+     */

+    public void start() { 

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

+            String factName = m_factories[j].getName();

+            String className = m_factories[j].getClassName(); 

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

+                if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {

+                    createInstance(m_factories[j], m_configurations[i]);

+                }

+            }

+        }

+        checkValidity();

+    }

+

+    /**

+     * Check handler validity.

+     * The method update the validaity of the handler.

+     */

+    private void checkValidity() {

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

+            if (m_configurations[i].getInstance() == null || m_configurations[i].getInstance().getState() != ComponentInstance.VALID) {

+                setValidity(false);

+                return;

+            }

+        }

+        setValidity(true);

+    }

+

+    /**

+     *  Instance state listener.

+     *  This method listens when managed instance states change.

+     *  @param instance : instance

+     *  @param newState : the now state of the given instance

+     *  @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)

+     */

+    public void stateChanged(ComponentInstance instance, int newState) {

+        switch (newState) {

+            case ComponentInstance.DISPOSED:

+            case ComponentInstance.STOPPED:

+                break; // Should not happen

+            case ComponentInstance.VALID:

+                if (!getValidity()) {

+                    checkValidity();

+                }

+                break;

+            case ComponentInstance.INVALID:

+                if (getValidity()) {

+                    checkValidity();

+                }

+                break;

+            default:

+                break;

+

+        }

+    }

+

+    /**

+     * Method returning an instance object of the given component type.

+     * This method must be called only on 'primitive' type.

+     * @param type : type.

+     * @return an instance object or null if not found.

+     */

+    public Object getObjectFromInstance(String type) {

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

+            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory())) {

+                if (m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {

+                    return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();

+                } else {

+                    error("An object cannot be get from the instance of the type " + type + ": invalid instance" + m_configurations[i].getInstance().getInstanceDescription().getDescription());

+                    return null;

+                }

+            }

+        }

+        return null;

+    }

+

+    /**

+     * Return the handler description, i.e. the state of created instances.

+     * @return the handler description.

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

+     */

+    public HandlerDescription getDescription() {

+        List list = new ArrayList();

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

+            list.add(m_configurations[i]);

+        }

+        return new InstanceHandlerDescription(this, list);

+    }

+

+    /**

+     * Get the list of used component type.

+     * @return the list containing the used component type

+     */

+    public List getUsedType() {

+        List result = new ArrayList();

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

+            result.add(m_configurations[i].getConfiguration().get("component"));

+        }

+        return result;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
similarity index 93%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
index 844e3e6..2be1122 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
@@ -1,90 +1,90 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.instance;
-
-import java.util.List;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Description of the Instance Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class InstanceHandlerDescription extends HandlerDescription {
-
-    /**
-     * List of managed instances.
-     */
-    private List m_instances;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : handler
-     * @param insts : list of component instances
-     */
-    public InstanceHandlerDescription(CompositeHandler h, List insts) {
-        super(h);
-        m_instances = insts;
-    }
-
-    /**
-     * Build handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element instances = super.getHandlerInfo();
-        for (int i = 0; i < m_instances.size(); i++) {
-            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);
-            Element instance = new Element("Instance", "");
-            if (inst.getInstance() != null) {
-                instance.addAttribute(new Attribute("Factory", inst.getFactory()));
-                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));
-                String state = null;
-                switch(inst.getInstance().getState()) {
-                    case ComponentInstance.DISPOSED : 
-                        state = "disposed"; break;
-                    case ComponentInstance.STOPPED : 
-                        state = "stopped"; break;
-                    case ComponentInstance.VALID : 
-                        state = "valid"; break;
-                    case ComponentInstance.INVALID : 
-                        state = "invalid"; break;
-                    default :
-                        break;
-                }
-                instance.addAttribute(new Attribute("State", state));
-                instance.addElement(inst.getInstance().getInstanceDescription().getDescription());
-            } else {
-                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));
-                instance.addAttribute(new Attribute("State", "Not Available"));
-            }
-            instances.addElement(instance);
-        }
-        return instances;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.instance;

+

+import java.util.List;

+

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

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

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

+import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;

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

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

+

+/**

+ * Description of the Instance Handler.

+ * 

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

+ */

+public class InstanceHandlerDescription extends HandlerDescription {

+

+    /**

+     * List of managed instances.

+     */

+    private List m_instances;

+

+    /**

+     * Constructor.

+     * 

+     * @param handler : handler

+     * @param insts : list of component instances

+     */

+    public InstanceHandlerDescription(CompositeHandler handler, List insts) {

+        super(handler);

+        m_instances = insts;

+    }

+

+    /**

+     * Build handler description.

+     * @return the handler description

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

+     */

+    public Element getHandlerInfo() {

+        Element instances = super.getHandlerInfo();

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

+            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);

+            Element instance = new Element("Instance", "");

+            if (inst.getInstance() == null) { 

+                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));

+                instance.addAttribute(new Attribute("State", "Not Available"));

+            } else {

+                instance.addAttribute(new Attribute("Factory", inst.getFactory()));

+                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));

+                String state = null;

+                switch(inst.getInstance().getState()) {

+                    case ComponentInstance.DISPOSED : 

+                        state = "disposed"; break;

+                    case ComponentInstance.STOPPED : 

+                        state = "stopped"; break;

+                    case ComponentInstance.VALID : 

+                        state = "valid"; break;

+                    case ComponentInstance.INVALID : 

+                        state = "invalid"; break;

+                    default :

+                        break;

+                }

+                instance.addAttribute(new Attribute("State", state));

+                instance.addElement(inst.getInstance().getInstanceDescription().getDescription());

+            }

+            instances.addElement(instance);

+        }

+        return instances;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java
new file mode 100644
index 0000000..76f912c
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java
@@ -0,0 +1,371 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.instantiator;

+

+import java.util.ArrayList;

+import java.util.Comparator;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

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

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

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

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

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

+import org.apache.felix.ipojo.composite.instance.InstanceHandler;

+import org.apache.felix.ipojo.composite.util.SourceManager;

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+

+/**

+ * Service Instantiator Class. This handler allows to instantiate service

+ * instance inside the composition.

+ * 

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

+ */

+public class ServiceDependencyHandler extends CompositeHandler implements DependencyStateListener {

+

+    /**

+     * List of instances to manage.

+     */

+    private List/* <SvcInstance> */m_instances = new ArrayList();

+    

+    /**

+     * List of importers.

+     */

+    private List/* <ServiceImporter> */ m_importers = new ArrayList();

+    

+    /**

+     * Flag indicating if the handler has already finished the start method.

+     */

+    private boolean m_isStarted;

+

+    /**

+     * Source Managers.

+     */

+    private List m_sources;

+    

+    

+    /**

+     * Create a Service instance object form the given Element.

+     * This method parse the given element and configure the service instance object.

+     * @param service : the Element describing the service instance

+     * @throws ConfigurationException : the service instance cannot be created correctly

+     */

+    private void createServiceInstance(Element service) throws ConfigurationException {

+        String spec = service.getAttribute("specification");

+        if (spec == null) {

+            throw new ConfigurationException("Malformed service : the specification attribute is mandatory");

+        }

+        String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself

+        String givenFilter = service.getAttribute("filter");

+        if (givenFilter != null) {

+            filter = "(&" + filter + givenFilter + ")"; //NOPMD

+        }

+        

+        Filter fil;

+        try {

+            fil = getCompositeManager().getGlobalContext().createFilter(filter);

+        } catch (InvalidSyntaxException e) {

+            throw new ConfigurationException("Malformed filter " + filter + " : " + e.getMessage());

+        }

+        

+        Properties prop = new Properties();

+        Element[] props = service.getElements("property");

+        for (int k = 0; props != null && k < props.length; k++) {

+            try {

+                InstanceHandler.parseProperty(props[k], prop);

+            } catch (ParseException e) {

+                throw new ConfigurationException("An instance configuration is invalid : " + e.getMessage());

+            }

+        }

+        

+        String aggregate = service.getAttribute("aggregate");

+        boolean agg = aggregate != null && aggregate.equalsIgnoreCase("true");

+        

+        String optional = service.getAttribute("optional");

+        boolean opt = optional != null && optional.equalsIgnoreCase("true");

+        

+        int policy = DependencyModel.getPolicy(service);

+        

+        Comparator cmp = DependencyModel.getComparator(service, getCompositeManager().getGlobalContext());

+        

+        SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, fil, cmp, policy);

+        m_instances.add(inst);

+        

+        String sources = service.getAttribute("context-source");

+        if (sources != null) {

+            SourceManager source = new SourceManager(sources, filter, inst, getCompositeManager());

+            if (m_sources == null) {

+                m_sources = new ArrayList(1);

+            }

+            m_sources.add(source);

+        }

+    }

+    

+    /**

+     * Create a Service importer object from the given Element.

+     * This method parse the given element and configure the service importer object.

+     * @param imp : Element describing the import

+     * @param confFilter : instance filter customization

+     * @throws ConfigurationException : the service importer cannot be created correctly

+     */

+    private void createServiceImport(Element imp, Dictionary confFilter) throws ConfigurationException {

+        boolean optional = false;

+        boolean aggregate = false;

+        String specification = imp.getAttribute("specification");

+

+        if (specification == null) { 

+            // Malformed import

+            error("Malformed imports : the specification attribute is mandatory");

+            throw new ConfigurationException("Malformed imports : the specification attribute is mandatory");

+        } else {

+            String opt = imp.getAttribute("optional");

+            optional = opt != null && opt.equalsIgnoreCase("true");

+

+            String agg = imp.getAttribute("aggregate");

+            aggregate = agg != null && agg.equalsIgnoreCase("true");

+

+            String original = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself

+            String filter = original;

+            String givenFilter = imp.getAttribute("filter");

+            if (givenFilter != null) {

+                filter = "(&" + filter + givenFilter + ")"; //NOPMD

+            }

+

+            String identitity = imp.getAttribute("id");

+

+            String scope = imp.getAttribute("scope");

+            BundleContext context = getCompositeManager().getGlobalContext(); // Get the default bundle context.

+            if (scope != null) {

+                if (scope.equalsIgnoreCase("global")) {

+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);

+                } else if (scope.equalsIgnoreCase("composite")) {

+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);

+                } else if (scope.equalsIgnoreCase("composite+global")) {

+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL_AND_GLOBAL);

+                }

+            }

+

+            // Configure instance filter if available

+            if (confFilter != null && identitity != null && confFilter.get(identitity) != null) {

+                filter = "(&" + original + (String) confFilter.get(identitity) + ")";

+            }

+

+            Filter fil = null;

+            if (filter != null) {

+                try {

+                    fil = getCompositeManager().getGlobalContext().createFilter(filter);

+                } catch (InvalidSyntaxException e) {

+                    throw new ConfigurationException("A required filter " + filter + " is malformed : " + e.getMessage());

+                }

+            }

+

+            Comparator cmp = DependencyModel.getComparator(imp, getCompositeManager().getGlobalContext());

+            Class spec = DependencyModel.loadSpecification(specification, getCompositeManager().getGlobalContext());

+            int policy = DependencyModel.getPolicy(imp);

+

+            ServiceImporter importer = new ServiceImporter(spec, fil, aggregate, optional, cmp, policy, context, identitity, this);

+            m_importers.add(importer);

+            

+            String sources = imp.getAttribute("context-source");

+            if (sources != null) {

+                SourceManager source = new SourceManager(sources, filter, importer, getCompositeManager());

+                if (m_sources == null) {

+                    m_sources = new ArrayList(1);

+                }

+                m_sources.add(source);

+            }

+            

+        }

+    }

+

+    /**

+     * Configure the handler.

+     * @param metadata : the metadata of the component

+     * @param conf : the instance configuration

+     * @throws ConfigurationException : the specification attribute is missing

+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

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

+        Element[] services = metadata.getElements("subservice");

+        // Get instance filters

+        Dictionary confFilter = null;

+        if (conf.get("requires.filters") != null) {

+            confFilter = (Dictionary) conf.get("requires.filters");

+        }

+        

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

+            String action = services[i].getAttribute("action");

+            if (action == null) {

+                throw new ConfigurationException("The action attribute must be set to 'instantiate' or 'import'");

+            } else if ("instantiate".equalsIgnoreCase(action)) {

+                createServiceInstance(services[i]);

+            } else if ("import".equalsIgnoreCase(action)) {

+                createServiceImport(services[i], confFilter);

+            } else {

+                throw new ConfigurationException("Unknown action : " + action);

+            }

+            

+            

+

+        }

+    }

+

+    /**

+     * Start the service instantiator handler.

+     * Start all created service instance.

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

+     */

+    public void start() {

+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {

+            SourceManager source = (SourceManager) m_sources.get(i);

+            source.start();

+        }

+        

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

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

+            imp.start();

+        }

+        

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

+            SvcInstance inst = (SvcInstance) m_instances.get(i);

+            inst.start();

+        }

+

+        isHandlerValid();

+        m_isStarted = true;

+    }

+

+    /**

+     * Check the handler validity.

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

+     */

+    private void isHandlerValid() {

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

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

+            if (imp.getState() != DependencyModel.RESOLVED) {

+                setValidity(false);

+                return;

+            }

+        }

+        

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

+            SvcInstance inst = (SvcInstance) m_instances.get(i);

+            if (inst.getState() != DependencyModel.RESOLVED) {

+                setValidity(false);

+                return;

+            }

+        }

+        

+        setValidity(true);

+    }

+

+    /**

+     * Handler stop method.

+     * Stop all created service instance.

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

+     */

+    public void stop() {

+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {

+            SourceManager source = (SourceManager) m_sources.get(i);

+            source.stop();

+        }

+        

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

+            SvcInstance inst = (SvcInstance) m_instances.get(i);

+            inst.stop();

+        }

+        

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

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

+            imp.stop();

+        }

+

+        m_isStarted = false;

+    }

+    

+    /**

+     * State change callback.

+     * This method is used to freeze the set of used provider if the static binding policy is used.

+     * @param newState : the new state of the underlying instance

+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)

+     */

+    public void stateChanged(int newState) {

+        // If we are becoming valid and started, check if we need to freeze importers.

+        if (m_isStarted && newState == ComponentInstance.VALID) { 

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

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

+                if (imp.getBindingPolicy() == DependencyModel.STATIC_BINDING_POLICY) {

+                    imp.freeze();

+                }

+            }

+            

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

+                SvcInstance imp = (SvcInstance) m_instances.get(i);

+                if (imp.getBindingPolicy() == DependencyModel.STATIC_BINDING_POLICY) {

+                    imp.freeze();

+                }

+            }

+        }

+    }

+

+    /**

+     * An service instance becomes valid.

+     * @param dep : dependency becoming valid.

+     */

+    public void validate(DependencyModel dep) {

+        if (!getValidity()) {

+            isHandlerValid();

+        }

+    }

+

+    /**

+     * A service instance becomes invalid.

+     * @param dep : dependency becoming valid.

+     */

+    public void invalidate(DependencyModel dep) {

+        if (getValidity()) {

+            isHandlerValid();

+        }

+    }

+

+    /**

+     * Get the service instantiator handler description.

+     * @return the description

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

+     */

+    public HandlerDescription getDescription() {

+        return new ServiceInstantiatorDescription(this, m_instances, m_importers);

+    }

+    

+    public List getInstances() {

+        return m_instances;

+    }

+    

+    public List getRequirements() {

+        return m_importers;

+    }

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java
new file mode 100644
index 0000000..019ebb0
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java
@@ -0,0 +1,319 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.instantiator;

+

+import java.util.ArrayList;

+import java.util.Comparator;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * Import a service form the parent to the internal service registry.

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

+ */

+public class ServiceImporter extends DependencyModel {

+

+    /**

+     * Reference on the handler.

+     */

+    private ServiceDependencyHandler m_handler;

+

+    private final class Record {

+        /**

+         * External Reference.

+         */

+        private ServiceReference m_ref;

+

+        /**

+         * Internal Registration.

+         */

+        private ServiceRegistration m_reg;

+

+        /**

+         * Exposed Object.

+         */

+        private Object m_svcObject;

+

+        /**

+         * Constructor.

+         * @param ref : service reference.

+         */

+        protected Record(ServiceReference ref) {

+            m_ref = ref;

+        }

+

+        /**

+         * Register the current import.

+         */

+        private void register() {

+            if (m_reg != null) {

+                m_reg.unregister();

+            }

+            m_svcObject = getService(m_ref);

+            m_reg = m_handler.getCompositeManager().getServiceContext().registerService(getSpecification().getName(), m_svcObject, getProps(m_ref));

+        }

+

+        /**

+         * Update the current import.

+         */

+        private void update() {

+            if (m_reg != null) {

+                m_reg.setProperties(getProps(m_ref));

+            }

+        }

+

+        /**

+         * Unregister and release the current import.

+         */

+        private void dispose() {

+            if (m_reg != null) {

+                m_reg.unregister();

+                m_svcObject = null;

+                m_reg = null;

+            }

+            m_ref = null;

+        }

+

+        /**

+         * Test object equality.

+         * @param object : object to confront against the current object.

+         * @return true if the two objects are equals (same service reference).

+         * @see java.lang.Object#equals(java.lang.Object)

+         */

+        public boolean equals(Object object) {

+            if (object instanceof Record) {

+                Record rec = (Record) object;

+                return rec.m_ref == m_ref;

+            }

+            return false;

+        }

+        

+        /**

+         * Hash code method.

+         * @return the hash code by calling the parent method.

+         */

+        public int hashCode() {

+            return super.hashCode();

+        }

+    }

+

+    /**

+     * List of managed records.

+     */

+    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;

+

+    /**

+     * Requirement Id.

+     */

+    private String m_id;

+

+    /**

+     * Is this requirement attached to a service-level requirement.

+     */

+    private boolean m_specLevelReq;

+

+    /**

+     * Is the set of used provider frozen ?

+     */

+    private boolean m_isFrozen;

+

+    /**

+     * Constructor.

+     * 

+     * @param specification : targeted specification

+     * @param filter : LDAP filter

+     * @param multiple : should the importer imports several services ?

+     * @param optional : is the import optional ?

+     * @param cmp : comparator to use for the tracking 

+     * @param policy : resolving policy

+     * @param context : bundle context to use for the tracking (can be a servie context)

+     * @param identitity : requirement id (may be null)

+     * @param handler : handler

+     */

+    public ServiceImporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, BundleContext context, String identitity

+            , ServiceDependencyHandler handler) {

+        super(specification, multiple, optional, filter, cmp, policy, context, handler);

+

+        this.m_handler = handler;

+

+        if (m_id == null) {

+            m_id = super.getSpecification().getName();

+        } else {

+            m_id = identitity;

+        }

+

+    }

+

+    /**

+     * Get the properties for the exposed service from the given reference.

+     * 

+     * @param ref : the reference.

+     * @return the property dictionary

+     */

+    private static Dictionary getProps(ServiceReference ref) {

+        Properties prop = new Properties();

+        String[] keys = ref.getPropertyKeys();

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

+            prop.put(keys[i], ref.getProperty(keys[i]));

+        }

+        return prop;

+    }

+

+    /**

+     * Freeze the set of used provider.

+     * This method allow to fix the set of provider when the static binding policy is used.

+     */

+    public void freeze() {

+        m_isFrozen = true;

+    }

+

+    public boolean isFrozen() {

+        return m_isFrozen;

+    }

+

+    /**

+     * Stop the management of the import.

+     */

+    public void stop() {

+

+        super.stop();

+

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

+            Record rec = (Record) m_records.get(i);

+            rec.dispose();

+        }

+

+        m_records.clear();

+

+    }

+

+    /**

+     * Get the record list using the given reference.

+     * 

+     * @param ref : the reference

+     * @return the list containing all record using the given reference

+     */

+    private List/* <Record> */getRecordsByRef(ServiceReference ref) {

+        List list = new ArrayList();

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

+            Record rec = (Record) m_records.get(i);

+            if (rec.m_ref == ref) {

+                list.add(rec);

+            }

+        }

+        return list;

+    }

+

+    /**

+     * Build the list of imported service provider.

+     * @return the list of all imported services.

+     */

+    public List getProviders() {

+        List list = new ArrayList();

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

+            list.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));

+        }

+        return list;

+    }

+

+    /**

+     * Set that this dependency is a service level dependency.

+     * This forces the scoping policy to be STRICT. 

+     * @param b

+     */

+    public void setServiceLevelDependency() {

+        m_specLevelReq = true;

+        PolicyServiceContext context = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);

+        setBundleContext(context);

+    }

+

+    public String getId() {

+        return m_id;

+    }

+

+    public boolean isServiceLevelRequirement() {

+        return m_specLevelReq;

+    }

+

+    /**

+     * On Dependency Reconfiguration notification method.

+     * @param departs : leaving service references.

+     * @param arrivals : new injected service references.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])

+     */

+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {

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

+            onServiceDeparture(departs[i]);

+        }

+        

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

+            onServiceArrival(arrivals[i]);

+        }

+    }

+

+    /**

+     * A new service is injected by the tracker.

+     * This method create a 'Record' and register it.

+     * @param ref : new service reference.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceArrival(ServiceReference ref) {

+        Record rec = new Record(ref);

+        m_records.add(rec);

+        // Always register the reference, as the method is call only when needed. 

+        rec.register();

+    }

+

+    /**

+     * A used service disappears.

+     * This method find the implicated 'Record', dispose it and remove it from the list.

+     * @param ref : leaving service reference.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceDeparture(ServiceReference ref) {

+        List list = getRecordsByRef(ref);

+        for (int i = 0; i < list.size(); i++) { // Stop the implied record

+            Record rec = (Record) list.get(i);

+            rec.dispose();

+        }

+        m_records.removeAll(list);

+    }

+

+    /**

+     * A used service is modified.

+     * @param ref : modified service reference.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceModification(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceModification(ServiceReference ref) {

+        List list = getRecordsByRef(ref);

+        for (int i = 0; i < list.size(); i++) { // Stop the implied record

+            Record rec = (Record) list.get(i);

+            rec.update();

+        }

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
new file mode 100644
index 0000000..2125153
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
@@ -0,0 +1,117 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.instantiator;

+

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

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

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

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

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

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

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

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Description of the Service Creator Handler.

+ * 

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

+ */

+public class ServiceInstantiatorDescription extends HandlerDescription {

+

+    /**

+     * List of managed service instances.

+     */

+    private List m_instances;

+

+    /**

+     * List of exports.

+     */

+    private List m_imports;

+

+    /**

+     * Constructor.

+     * 

+     * @param handler : composite handler

+     * @param insts : list of service instances

+     * @param imps : list of service importers

+     */

+    public ServiceInstantiatorDescription(CompositeHandler handler, List insts, List imps) {

+        super(handler);

+        m_instances = insts;

+        m_imports = imps;

+    }

+

+    /**

+     * Build service instantiator handler description.

+     * @return the handler description

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

+     */

+    public Element getHandlerInfo() {

+        Element services = super.getHandlerInfo();

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

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

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

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

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

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

+            }

+            if (imp.getState() == DependencyModel.RESOLVED) {

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

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

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

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

+                    impo.addElement(prov);

+                }

+            } else {

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

+            }

+            services.addElement(impo);

+        }

+        

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

+            SvcInstance inst = (SvcInstance) m_instances.get(i);

+            Element service = new Element("Service", "");

+            service.addAttribute(new Attribute("Specification", inst.getServiceSpecification()));

+            String state = "unresolved";

+            if (inst.getState() == DependencyModel.RESOLVED) {

+                state = "resolved";

+            }

+            service.addAttribute(new Attribute("State", state));

+            Map map = inst.getMatchingFactories();

+            Set keys = map.keySet();

+            Iterator iterator = keys.iterator();

+            while (iterator.hasNext()) {

+                ServiceReference ref = (ServiceReference) iterator.next();

+                Object object = map.get(ref);

+                if (object != null) {

+                    Element fact = new Element("Factory", "");

+                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) object).getFactory().getName()));

+                    service.addElement(fact);

+                }

+            }

+            services.addElement(service);

+        }

+        return services;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
new file mode 100644
index 0000000..94c0a09
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
@@ -0,0 +1,267 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.instantiator;

+

+import java.util.Comparator;

+import java.util.Dictionary;

+import java.util.Enumeration;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Properties;

+import java.util.Set;

+

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

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

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

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

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

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

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

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

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Manage a service instantiation. This service create component instance providing the required service specification.

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

+ */

+public class SvcInstance extends DependencyModel {

+

+    /**

+     * Configuration to push to the instance.

+     */

+    private Dictionary m_configuration;

+

+    /**

+     * Handler creating the service instance.

+     */

+    private ServiceDependencyHandler m_handler;

+

+    /**

+     * Map of matching factories Service Reference => instance or null (null if the service reference is not actually used).

+     */

+    private Map /* <ServiceReference, Instance> */m_factories = new HashMap();

+

+    /**

+     * Required specification.

+     */

+    private String m_specification;

+

+    /**

+     * Is the service provider frozen ? (Is used for static biding policy)

+     */

+    private boolean m_isFrozen;

+

+    /**

+     * Constructor.

+     * @param handler : the handler.

+     * @param spec : required specification.

+     * @param conf : instance configuration.

+     * @param isAgg : is the service instance an aggregate service ?

+     * @param isOpt : is the service instance optional ?

+     * @param filt : LDAP filter

+     * @param cmp : comparator to use for the tracking

+     * @param policy : binding policy

+     * @throws ConfigurationException : an attribute cannot be parsed correctly, or is incorrect.

+     */

+    public SvcInstance(ServiceDependencyHandler handler, String spec, Dictionary conf, boolean isAgg, boolean isOpt, Filter filt, Comparator cmp, int policy) throws ConfigurationException {

+        super(Factory.class, isAgg, isOpt, filt, cmp, policy, null, handler);

+

+        m_specification = spec;

+

+        m_handler = handler;

+        setBundleContext(m_handler.getCompositeManager().getServiceContext());

+

+        m_configuration = conf;

+    }

+

+    /**

+     * Stop the service instance.

+     */

+    public void stop() {

+        super.stop();

+

+        Set keys = m_factories.keySet();

+        Iterator iterator = keys.iterator();

+        while (iterator.hasNext()) {

+            ServiceReference ref = (ServiceReference) iterator.next();

+            Object object = m_factories.get(ref);

+            if (object != null) {

+                ((ComponentInstance) object).dispose();

+            }

+        }

+

+        m_factories.clear();

+

+    }

+

+    public boolean isFrozen() {

+        return m_isFrozen;

+    }

+

+    /**

+     * Freeze the set of used provider.

+     * This method is when the static binding policy is applied.

+     */

+    public void freeze() {

+        m_isFrozen = true;

+    }

+

+    /**

+     * Create an instance for the given reference. The instance is not added inside the map.

+     * @param factory : the factory from which we need to create the instance.

+     * @return the created component instance.

+     * @throws ConfigurationException : the instance cannot be configured correctly.

+     * @throws MissingHandlerException : the factory is invalid.

+     * @throws UnacceptableConfiguration : the given configuration is invalid for the given factory.

+     */

+    private ComponentInstance createInstance(Factory factory) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+        // Recreate the configuration to avoid sharing.

+        Properties props = new Properties();

+        Enumeration keys = m_configuration.keys();

+        while (keys.hasMoreElements()) {

+            String key = (String) keys.nextElement();

+            props.put(key, m_configuration.get(key));

+        }

+        ComponentInstance instance = null;

+        instance = factory.createComponentInstance(props);

+        return instance;

+    }

+

+    /**

+     * Does the service instance match with the given factory ?

+     * @param fact : the factory to test.

+     * @return true if the factory match, false otherwise.

+     */

+    public boolean match(ServiceReference fact) {

+        // Check if the factory can provide the specification

+        ComponentTypeDescription desc = (ComponentTypeDescription) fact.getProperty("component.description");

+        if (desc == null) { 

+            return false; // No component type description.

+        }

+

+        String[] provides = desc.getprovidedServiceSpecification();

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

+            if (provides[i].equals(m_specification)) {

+                // Check that the factory needs every properties contained in

+                // the configuration

+                PropertyDescription[] props = desc.getProperties();

+                Properties conf = new Properties();

+                Enumeration keys = m_configuration.keys();

+                while (keys.hasMoreElements()) {

+                    String key = (String) keys.nextElement();

+                    if (!containsProperty(key, props)) { return false; }

+                    conf.put(key, m_configuration.get(key));

+                }

+

+                Factory factory = (Factory) getService(fact);

+                return factory.isAcceptable(conf);

+            }

+        }

+        return false;

+    }

+

+    /**

+     * Does the factory support the given property ? This method check if the property is contained in the given property description array.

+     * @param name : name of the property

+     * @param props : list of property description

+     * @return true if the factory support this property

+     */

+    private boolean containsProperty(String name, org.apache.felix.ipojo.architecture.PropertyDescription[] props) {

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

+            if (props[i].getName().equalsIgnoreCase(name)) { return true; }

+        }

+        if (name.equalsIgnoreCase("name")) { return true; } // Skip the name property

+        return false;

+    }

+

+    /**

+     * Get the required specification.

+     * @return the required specification.

+     */

+    public String getServiceSpecification() {

+        return m_specification;

+    }

+

+    /**

+     * Get the map of used references [reference, component instance].

+     * @return the map of used references.

+     */

+    protected Map getMatchingFactories() {

+        return m_factories;

+    }

+

+    /**

+     * On Dependency Reconfiguration notification method.

+     * @param departs : leaving service references.

+     * @param arrivals : new injected service references.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])

+     */

+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {

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

+            onServiceDeparture(departs[i]);

+        }

+        

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

+            onServiceArrival(arrivals[i]);

+        }

+    }

+

+    /**

+     * A new service is injected.

+     * This method create the sub-service instance in the composite.

+     * @param ref : service reference.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceArrival(ServiceReference ref) {

+        // The given factory matches.

+        try {

+            Factory fact = (Factory) getService(ref);

+            ComponentInstance instance = createInstance(fact);

+            m_factories.put(ref, instance);

+        } catch (UnacceptableConfiguration e) {

+            m_handler.error("A matching factory refuse the actual configuration : " + e.getMessage());

+            m_handler.getCompositeManager().stop();

+        } catch (MissingHandlerException e) {

+            m_handler.error("A matching factory is no more valid : " + e.getMessage());

+            m_handler.getCompositeManager().stop();

+        } catch (ConfigurationException e) {

+            m_handler.error("A matching configuration is refuse by the instance : " + e.getMessage());

+            m_handler.getCompositeManager().stop();

+        }

+

+    }

+

+    

+    /**

+     * A used service is leaving.

+     * This method dispose the created instance.

+     * @param ref : leaving service reference.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceDeparture(ServiceReference ref) {

+        // Remove the reference is contained

+        Object instance = m_factories.remove(ref);

+        if (instance != null) {

+            ((ComponentInstance) instance).dispose();

+        }

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
similarity index 82%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
index 4202643..9423d3c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
@@ -1,55 +1,41 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-/**
- * Exception occurs when a composition error occurs.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositionException extends Exception {
-
-    /**
-     * serialVersionUID.
-     */
-    private static final long serialVersionUID = -3063353267573738105L;
-
-    /**
-     * Message.
-     */
-    private String m_message;
-
-    /**
-     * Constructor.
-     * @param message : a message.
-     */
-    public CompositionException(String message) {
-        m_message = message;
-    }
-
-    /**
-     * Get the exception message.
-     * @return the message.
-     * @see java.lang.Throwable#getMessage()
-     */
-    public String getMessage() {
-        return m_message;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+/**

+ * Exception occurs when a composition error occurs.

+ * 

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

+ */

+public class CompositionException extends Exception {

+    //TODO consider removing this class to use configuration exception.

+    /**

+     * serialVersionUID.

+     */

+    private static final long serialVersionUID = -3063353267573738105L;

+

+    /**

+     * Constructor.

+     * @param message : a message.

+     */

+    public CompositionException(String message) {

+        super(message);

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
similarity index 78%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
index da54207..8ccf749 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
@@ -1,363 +1,359 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.manipulation.Manipulator;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Check and build a composition, i.e. a POJO containing the composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class CompositionMetadata {
-
-    /**
-     * Implemented composition.
-     */
-    private SpecificationMetadata m_specification;
-
-    /**
-     * Name of the composition.
-     */
-    private String m_name;
-
-    /**
-     * Bundle Context.
-     */
-    private BundleContext m_context;
-    
-    /**
-     * Manipulation Metadata.
-     */
-    private Element m_manipulationMetadata;
-
-    /**
-     * Reference on the handler.
-     */
-    private ProvidedServiceHandler m_handler;
-
-    /**
-     * List of Mappings.
-     */
-    private List m_mappings = new ArrayList();
-
-    /**
-     * Constructor.
-     * @param bc : bundle context
-     * @param description : 'provides' element
-     * @param psh : parent handler 
-     * @param name : name of the composition.
-     */
-    public CompositionMetadata(BundleContext bc, Element description, ProvidedServiceHandler psh, String name) {
-        m_context = bc;
-        m_handler = psh;
-        // Get the composition name
-        m_name = description.getAttribute("specification") + name;
-
-        // Get implemented service specification
-        String spec = description.getAttribute("specification");
-        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);        
-
-        Element[] mappings = description.getElements("delegation");
-        for (int i = 0; i < mappings.length; i++) {
-            String methodName = mappings[i].getAttribute("method");
-            MethodMetadata method = m_specification.getMethodByName(methodName);
-            if (method == null) {
-                m_handler.log(Logger.ERROR, "The method " + methodName + " does not exist in the specicifation " + spec);
-                return;
-            }
-
-            if (mappings[i].getAttribute("policy").equalsIgnoreCase("All")) {
-                method.setAllPolicy();
-            }
-        }
-    }
-
-    protected BundleContext getBundleContext() {
-        return m_context;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public SpecificationMetadata getSpecificationMetadata() {
-        return m_specification;
-    }
-
-    /**
-     * Build Available Mappings.
-     * @throws CompositionException : a factory is not available, the composition cannot be checked.
-     */
-    private void buildAvailableMappingList() throws CompositionException {
-        int index = 0;
-        
-        for (int i = 0; i < m_handler.getInstanceType().size(); i++) {
-            String type = (String) m_handler.getInstanceType().get(i);
-            try {
-                ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(factory.name=" + type + ")");
-                if (refs == null) {
-                    m_handler.log(Logger.ERROR, "The factory " + type + " is not available, cannot check the composition");
-                    throw new CompositionException("The factory " + type + " needs to be available to check the composition");
-                } else {
-                    String className = (String) refs[0].getProperty("component.class");
-                    Class impl = m_context.getBundle().loadClass(className);
-                    SpecificationMetadata spec = new SpecificationMetadata(impl, type, m_handler);
-                    FieldMetadata field = new FieldMetadata(spec);
-                    field.setName("_field" + index);
-                    Mapping map = new Mapping(spec, field);
-                    m_mappings.add(map);
-                    index++;
-                }
-            } catch (InvalidSyntaxException e) {
-                m_handler.log(Logger.ERROR, "A LDAP filter is not valid : " + e.getMessage());
-            } catch (ClassNotFoundException e) {
-                m_handler.log(Logger.ERROR, "The implementation class of a component cannot be loaded : " + e.getMessage());
-            }
-        }
-
-        for (int i = 0; i < m_handler.getSpecifications().size(); i++) {
-            SpecificationMetadata spec = (SpecificationMetadata) m_handler.getSpecifications().get(i);
-            FieldMetadata field = new FieldMetadata(spec);
-            field.setName("_field" + index);
-            if (spec.isOptional()) {
-                field.setOptional(true);
-            }
-            if (spec.isAggregate()) {
-                field.setAggregate(true);
-            }
-            Mapping map = new Mapping(spec, field);
-            m_mappings.add(map);
-            index++;
-        }
-    }
-    
-
-    /**
-     * Build the delegation mapping.
-     * @throws CompositionException : occurs when the mapping cannot be inferred correctly
-     */
-    protected void buildMapping() throws CompositionException {
-        buildAvailableMappingList();
-
-        // Dependency closure is OK, now look for method delegation
-        Map/* <MethodMetadata, Mapping> */availableSvcMethods = new HashMap();
-        Map/* <MethodMetadata, Mapping> */availableInstMethods = new HashMap();
-
-        for (int i = 0; i < m_mappings.size(); i++) {
-            Mapping map = (Mapping) m_mappings.get(i);
-            SpecificationMetadata spec = map.getSpecification();
-            for (int j = 0; j < spec.getMethods().size(); j++) {
-                MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);
-                if (spec.isInterface()) { 
-                    availableSvcMethods.put(method, map);
-                } else {
-                    availableInstMethods.put(method, map);
-                }
-            }
-        }
-
-        // For each needed method, search if available and store the mapping
-        for (int j = 0; j < m_specification.getMethods().size(); j++) {
-            MethodMetadata method = (MethodMetadata) m_specification.getMethods().get(j);
-            Set keys = availableInstMethods.keySet(); // Look first in methods contained in the glue code.
-            Iterator it = keys.iterator();
-            boolean found = false;
-            while (it.hasNext() & !found) {
-                MethodMetadata met = (MethodMetadata) it.next();
-                if (met.equals(method)) {
-                    found = true;
-                    FieldMetadata field = ((Mapping) availableInstMethods.get(met)).getField();
-                    field.setUseful(true);
-                    method.setDelegation(field);
-                }
-            }
-            if (!found) { // If not found looks inside method contained in services.
-                keys = availableSvcMethods.keySet(); // Look first in methods contained in the glue code
-                it = keys.iterator();
-                while (!found && it.hasNext()) {
-                    MethodMetadata met = (MethodMetadata) it.next();
-                    if (met.equals(method)) {
-                        found = true;
-                        FieldMetadata field = ((Mapping) availableSvcMethods.get(met)).getField();
-                        field.setUseful(true);
-                        method.setDelegation(field);
-                        // Test optional
-                        if (field.isOptional() && !method.throwsUnsupportedOperationException()) {
-                            m_handler.log(Logger.WARNING, "The method " + method.getMethod().getName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
-                        }
-                    }
-                }
-            }
-            if (!found) {
-                throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated");
-            }
-        }
-    }
-
-    /**
-     * Build a service implementation.
-     * @return the byte[] of the POJO.
-     */
-    protected byte[] buildPOJO() {
-        Class clazz = null;
-        try {
-            clazz = getBundleContext().getBundle().loadClass(m_specification.getName());
-        } catch (ClassNotFoundException e1) {
-            //TODO
-            e1.printStackTrace();
-        }
-        byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList());
-        Manipulator m = new Manipulator();
-        try {
-            byte[] ff = m.manipulate(pojo);
-            m_manipulationMetadata = m.getManipulationMetadata();
-            return ff;
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    /**
-     * Build service implementation metadata.
-     * @param in : name of the future instance (used to avoid cycle)
-     * @return Component Type metadata. 
-     */
-    protected Element buildMetadata(String in) {
-        Element elem = new Element("component", "");
-        Attribute className = new Attribute("className", m_name);
-        Attribute factory = new Attribute("factory", "false");
-        elem.addAttribute(className);
-        elem.addAttribute(factory);
-        
-        // Add architecture for debug
-        elem.addAttribute(new Attribute("architecture", "true"));
-
-        // Provides
-        Element provides = new Element("provides", "");
-        provides.addAttribute(new Attribute("specification", m_specification.getName()));
-        elem.addElement(provides);
-
-        // Dependencies
-        List fields = getFieldList();
-        for (int i = 0; i < fields.size(); i++) {
-            FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful() && field.getSpecification().isInterface()) {
-                Element dep = new Element("requires", "");
-                dep.addAttribute(new Attribute("field", field.getName()));
-                dep.addAttribute(new Attribute("scope", "composite"));
-                if (field.getSpecification().isOptional()) {
-                    dep.addAttribute(new Attribute("optional", "true"));
-                }
-                dep.addAttribute(new Attribute("filter", "(!(instance.name=" + in + "))"));
-                elem.addElement(dep);
-            }
-        }
-        
-        Element properties = new Element("properties", "");
-        for (int i = 0; i < fields.size(); i++) {
-            FieldMetadata field = (FieldMetadata) fields.get(i);
-            if (field.isUseful() &&  ! field.getSpecification().isInterface()) {
-                Element prop = new Element("Property", "");
-                prop.addAttribute(new Attribute("field", field.getName()));
-                properties.addElement(prop);
-            }
-        }
-        if (properties.getElements().length != 0) {
-            elem.addElement(properties);
-        }
-
-        // Insert information to metadata
-        elem.addElement(m_manipulationMetadata);
-        
-        return elem;
-    }
-
-    /**
-     * Get the field list to use for the delegation.
-     * @return the field list.
-     */
-    public List getFieldList() {
-        List list = new ArrayList();
-        for (int i = 0; i < m_mappings.size(); i++) {
-            Mapping map = (Mapping) m_mappings.get(i);
-            list.add(map.getField());
-        }
-        return list;
-    }
-
-    /**
-     * Get the method list contained in the implemented specification.
-     * @return the List of implemented method.
-     */
-    private List getMethodList() {
-        return m_specification.getMethods();
-    }
-    
-    /**
-     * Store links between Field and pointed Specification.
-     */
-    private class Mapping {
-
-        /**
-         * Specification.
-         */
-        private SpecificationMetadata m_spec;
-
-        /**
-         * Field.
-         */
-        private FieldMetadata m_field;
-
-        /**
-         * Constructor.
-         * @param spec : specification metadata.
-         * @param field : the field.
-         */
-        public Mapping(SpecificationMetadata spec, FieldMetadata field) {
-            m_spec = spec;
-            m_field = field;
-        }
-
-        public SpecificationMetadata getSpecification() {
-            return m_spec;
-        }
-
-        public FieldMetadata getField() {
-            return m_field;
-        }
-
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Check and build a composition, i.e. a POJO containing the composition.

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

+ */

+public class CompositionMetadata {

+

+    /**

+     * Implemented composition.

+     */

+    private SpecificationMetadata m_specification;

+

+    /**

+     * Name of the composition.

+     */

+    private String m_name;

+

+    /**

+     * Bundle Context.

+     */

+    private BundleContext m_context;

+

+    /**

+     * Manipulation Metadata.

+     */

+    private Element m_manipulation;

+

+    /**

+     * Reference on the handler.

+     */

+    private ProvidedServiceHandler m_handler;

+

+    /**

+     * List of Mappings.

+     */

+    private List m_mappings = new ArrayList();

+

+    /**

+     * Constructor.

+     * @param context : bundle context

+     * @param description : 'provides' element

+     * @param psh : parent handler 

+     * @param name : name of the composition.

+     */

+    public CompositionMetadata(BundleContext context, Element description, ProvidedServiceHandler psh, String name) {

+        m_context = context;

+        m_handler = psh;

+        // Get the composition name

+        m_name = description.getAttribute("specification") + name;

+

+        // Get implemented service specification

+        String spec = description.getAttribute("specification");

+        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);

+

+        Element[] mappings = description.getElements("delegation");

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

+            String methodName = mappings[i].getAttribute("method");

+            MethodMetadata method = m_specification.getMethodByName(methodName);

+            if (method == null) {

+                m_handler.error("The method " + methodName + " does not exist in the specicifation " + spec);

+                return;

+            }

+

+            if (mappings[i].getAttribute("policy").equalsIgnoreCase("All")) {

+                method.setAllPolicy();

+            }

+        }

+    }

+

+    protected BundleContext getBundleContext() {

+        return m_context;

+    }

+

+    public String getName() {

+        return m_name;

+    }

+

+    public SpecificationMetadata getSpecificationMetadata() {

+        return m_specification;

+    }

+

+    /**

+     * Build Available Mappings.

+     * @throws CompositionException : a factory is not available, the composition cannot be checked.

+     */

+    private void buildAvailableMappingList() throws CompositionException {

+        int index = 0;

+

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

+            String type = (String) m_handler.getInstanceType().get(i);

+            try {

+                ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(factory.name=" + type + ")");

+                if (refs == null) {

+                    m_handler.error("The factory " + type + " is not available, cannot check the composition");

+                    throw new CompositionException("The factory " + type + " needs to be available to check the composition");

+                } else {

+                    String className = (String) refs[0].getProperty("component.class");

+                    Class impl = m_context.getBundle().loadClass(className);

+                    SpecificationMetadata spec = new SpecificationMetadata(impl, type, m_handler);

+                    FieldMetadata field = new FieldMetadata(spec);

+                    field.setName("_field" + index);

+                    Mapping map = new Mapping(spec, field);

+                    m_mappings.add(map);

+                    index++;

+                }

+            } catch (InvalidSyntaxException e) {

+                m_handler.error("A LDAP filter is not valid : " + e.getMessage());

+            } catch (ClassNotFoundException e) {

+                m_handler.error("The implementation class of a component cannot be loaded : " + e.getMessage());

+            }

+        }

+

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

+            SpecificationMetadata spec = (SpecificationMetadata) m_handler.getSpecifications().get(i);

+            FieldMetadata field = new FieldMetadata(spec);

+            field.setName("_field" + index);

+            if (spec.isOptional()) {

+                field.setOptional(true);

+            }

+            if (spec.isAggregate()) {

+                field.setAggregate(true);

+            }

+            Mapping map = new Mapping(spec, field);

+            m_mappings.add(map);

+            index++;

+        }

+    }

+

+    /**

+     * Build the delegation mapping.

+     * @throws CompositionException : occurs when the mapping cannot be inferred correctly

+     */

+    protected void buildMapping() throws CompositionException {

+        buildAvailableMappingList();

+

+        // Dependency closure is OK, now look for method delegation

+        Map/* <MethodMetadata, Mapping> */svcMethods = new HashMap();

+        Map/* <MethodMetadata, Mapping> */instMethods = new HashMap();

+

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

+            Mapping map = (Mapping) m_mappings.get(i);

+            SpecificationMetadata spec = map.getSpecification();

+            for (int j = 0; j < spec.getMethods().size(); j++) {

+                MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);

+                if (spec.isInterface()) {

+                    svcMethods.put(method, map);

+                } else {

+                    instMethods.put(method, map);

+                }

+            }

+        }

+

+        // For each needed method, search if available and store the mapping

+        for (int j = 0; j < m_specification.getMethods().size(); j++) {

+            MethodMetadata method = (MethodMetadata) m_specification.getMethods().get(j);

+            Set keys = instMethods.keySet(); // Look first in methods contained in the glue code.

+            Iterator iterator = keys.iterator();

+            boolean found = false;

+            while (iterator.hasNext() & !found) {

+                MethodMetadata met = (MethodMetadata) iterator.next();

+                if (met.equals(method)) {

+                    found = true;

+                    FieldMetadata field = ((Mapping) instMethods.get(met)).getField();

+                    field.setUseful(true);

+                    method.setDelegation(field);

+                }

+            }

+            if (!found) { // If not found looks inside method contained in services.

+                keys = svcMethods.keySet(); // Look first in methods contained in the glue code

+                iterator = keys.iterator();

+                while (!found && iterator.hasNext()) {

+                    MethodMetadata met = (MethodMetadata) iterator.next();

+                    if (met.equals(method)) {

+                        found = true;

+                        FieldMetadata field = ((Mapping) svcMethods.get(met)).getField();

+                        field.setUseful(true);

+                        method.setDelegation(field);

+                        // Test optional

+                        if (field.isOptional() && !method.throwsUnsupportedOperationException()) {

+                            m_handler.warn("The method " + method.getMethod().getName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");

+                        }

+                    }

+                }

+            }

+            if (!found) { throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated"); }

+        }

+    }

+

+    /**

+     * Build a service implementation.

+     * @return the byte[] of the POJO.

+     */

+    protected byte[] buildPOJO() {

+        Class clazz = null;

+        try {

+            clazz = getBundleContext().getBundle().loadClass(m_specification.getName());

+        } catch (ClassNotFoundException e1) {

+            // The class has already be loaded.

+            return null;

+        }

+        byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList());

+        Manipulator manipulator = new Manipulator();

+        try {

+            byte[] newclazz = manipulator.manipulate(pojo);

+            m_manipulation = manipulator.getManipulationMetadata();

+            return newclazz;

+        } catch (IOException e) {

+            m_handler.error("An error occurs during the composite implementation creation : " + e.getMessage(), e);

+        }

+        return null;

+    }

+

+    /**

+     * Build service implementation metadata.

+     * @param name : name of the future instance (used to avoid cycle)

+     * @return Component Type metadata. 

+     */

+    protected Element buildMetadata(String name) {

+        Element elem = new Element("component", "");

+        Attribute className = new Attribute("className", m_name);

+        Attribute factory = new Attribute("factory", "false");

+        elem.addAttribute(className);

+        elem.addAttribute(factory);

+

+        // Add architecture for debug

+        elem.addAttribute(new Attribute("architecture", "true"));

+

+        // Provides

+        Element provides = new Element("provides", "");

+        provides.addAttribute(new Attribute("specification", m_specification.getName()));

+        elem.addElement(provides);

+

+        // Dependencies

+        List fields = getFieldList();

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

+            FieldMetadata field = (FieldMetadata) fields.get(i);

+            if (field.isUseful() && field.getSpecification().isInterface()) {

+                Element dep = new Element("requires", "");

+                dep.addAttribute(new Attribute("field", field.getName()));

+                dep.addAttribute(new Attribute("scope", "composite"));

+                if (field.getSpecification().isOptional()) {

+                    dep.addAttribute(new Attribute("optional", "true"));

+                }

+                dep.addAttribute(new Attribute("filter", "(!(instance.name=" + name + "))"));

+                elem.addElement(dep);

+            }

+        }

+

+        Element properties = new Element("properties", "");

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

+            FieldMetadata field = (FieldMetadata) fields.get(i);

+            if (field.isUseful() && !field.getSpecification().isInterface()) {

+                Element prop = new Element("Property", "");

+                prop.addAttribute(new Attribute("field", field.getName()));

+                properties.addElement(prop);

+            }

+        }

+        if (properties.getElements().length != 0) {

+            elem.addElement(properties);

+        }

+

+        // Insert information to metadata

+        elem.addElement(m_manipulation);

+

+        return elem;

+    }

+

+    /**

+     * Get the field list to use for the delegation.

+     * @return the field list.

+     */

+    public List getFieldList() {

+        List list = new ArrayList();

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

+            Mapping map = (Mapping) m_mappings.get(i);

+            list.add(map.getField());

+        }

+        return list;

+    }

+

+    /**

+     * Get the method list contained in the implemented specification.

+     * @return the List of implemented method.

+     */

+    private List getMethodList() {

+        return m_specification.getMethods();

+    }

+

+    /**

+     * Store links between Field and pointed Specification.

+     */

+    private class Mapping {

+

+        /**

+         * Specification.

+         */

+        private SpecificationMetadata m_spec;

+

+        /**

+         * Field.

+         */

+        private FieldMetadata m_field;

+

+        /**

+         * Constructor.

+         * @param spec : specification metadata.

+         * @param field : the field.

+         */

+        public Mapping(SpecificationMetadata spec, FieldMetadata field) {

+            m_spec = spec;

+            m_field = field;

+        }

+

+        public SpecificationMetadata getSpecification() {

+            return m_spec;

+        }

+

+        public FieldMetadata getField() {

+            return m_field;

+        }

+

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
similarity index 99%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
index 2839858..4df41a8 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
@@ -1,105 +1,105 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-/**
- * Field used inside a composition.
- * This class contains all information useful for the generation.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class FieldMetadata {
-
-    /**
-     * Name of the field.
-     */
-    private String m_name;
-
-    /**
-     * Is the field an array?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Interface of the field.
-     */
-    private SpecificationMetadata m_specification;
-
-    /**
-     * Is the field useful in this composition.
-     */
-    private boolean m_isUseful;
-
-    /**
-     * Is the dependency for this field optional.
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * Constructor.
-     * @param specification : interface of the field.
-     */
-    public FieldMetadata(SpecificationMetadata specification) {
-        super();
-        this.m_specification = specification;
-        if (m_specification.isAggregate()) {
-            m_isAggregate = true;
-        }
-    }
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    public void setAggregate(boolean aggregate) {
-        m_isAggregate = aggregate;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public void setName(String name) {
-        this.m_name = name;
-    }
-
-    public SpecificationMetadata getSpecification() {
-        return m_specification;
-    }
-
-    public void setSpecification(SpecificationMetadata specification) {
-        this.m_specification = specification;
-    }
-
-    public boolean isUseful() {
-        return m_isUseful;
-    }
-
-    public void setUseful(boolean useful) {
-        m_isUseful = useful;
-    }
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-    public void setOptional(boolean opt) {
-        m_isOptional = opt;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+/**

+ * Field used inside a composition.

+ * This class contains all information useful for the generation.

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

+ */

+public class FieldMetadata {

+

+    /**

+     * Name of the field.

+     */

+    private String m_name;

+

+    /**

+     * Is the field an array?

+     */

+    private boolean m_isAggregate = false;

+

+    /**

+     * Interface of the field.

+     */

+    private SpecificationMetadata m_specification;

+

+    /**

+     * Is the field useful in this composition.

+     */

+    private boolean m_isUseful;

+

+    /**

+     * Is the dependency for this field optional.

+     */

+    private boolean m_isOptional = false;

+

+    /**

+     * Constructor.

+     * @param specification : interface of the field.

+     */

+    public FieldMetadata(SpecificationMetadata specification) {

+        super();

+        this.m_specification = specification;

+        if (m_specification.isAggregate()) {

+            m_isAggregate = true;

+        }

+    }

+

+    public boolean isAggregate() {

+        return m_isAggregate;

+    }

+

+    public void setAggregate(boolean aggregate) {

+        m_isAggregate = aggregate;

+    }

+

+    public String getName() {

+        return m_name;

+    }

+

+    public void setName(String name) {

+        this.m_name = name;

+    }

+

+    public SpecificationMetadata getSpecification() {

+        return m_specification;

+    }

+

+    public void setSpecification(SpecificationMetadata specification) {

+        this.m_specification = specification;

+    }

+

+    public boolean isUseful() {

+        return m_isUseful;

+    }

+

+    public void setUseful(boolean useful) {

+        m_isUseful = useful;

+    }

+

+    public boolean isOptional() {

+        return m_isOptional;

+    }

+

+    public void setOptional(boolean opt) {

+        m_isOptional = opt;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
similarity index 65%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
index 5e209ae..510514e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
@@ -1,127 +1,138 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.lang.reflect.Method;
-
-/**
- * Information on Method for the composition.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class MethodMetadata {
-
-    /**
-     * ONE POLICY.
-     */
-    public static final int ONE_POLICY = 1;
-
-    /**
-     * ALL POLICY. 
-     */
-    public static final int ALL_POLICY = 2;
-
-    /**
-     * Method Object.
-     */
-    private Method m_method;
-    
-    /**
-     * Delegation field.
-     */
-    private FieldMetadata m_delegation;
-
-    /**
-     * Delegation policy (default = ONE).
-     */
-    private int m_policy = ONE_POLICY;
-
-    /**
-     * Constructor.
-     * @param method : method object.
-     */
-    public MethodMetadata(Method method) {
-        m_method = method;
-    }
-
-    public Method getMethod() {
-        return m_method;
-    }
-
-    public void setDelegation(FieldMetadata dm) {
-        m_delegation = dm;
-    }
-
-    public FieldMetadata getDelegation() {
-        return m_delegation;
-    }
-
-    /**
-     * Check if two method metadata are equals.
-     * @param mm : the method metadata to compare with the current method metadata.
-     * @return true if the two method are equals
-     */
-    public boolean equals(MethodMetadata mm) {
-        Method met = mm.getMethod();
-        return equals(met);
-    }
-
-    /**
-     * Equals method for Method object.
-     * @param met : the method object to compare.
-     * @return true if the given method signature is equals to the current method metadata.
-     */
-    public boolean equals(Method met) {
-        if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
-            return false;
-        }
-
-        for (int i = 0; i < m_method.getParameterTypes().length; i++) {
-            if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    public int getPolicy() {
-        return m_policy;
-    }
-
-    /**
-     * Activate the all policy for this method.
-     */
-    public void setAllPolicy() {
-        m_policy = ALL_POLICY;
-    }
-    
-    /**
-     * Check if the method can throw UnsupportedOperationException.
-     * @return true if the method has declared the UnsupportedOperationException.
-     */
-    boolean throwsUnsupportedOperationException() {
-        for (int i = 0; i < m_method.getExceptionTypes().length; i++) {
-            if (m_method.getExceptionTypes()[i].getName().equals(UnsupportedOperationException.class.getName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.lang.reflect.Method;

+

+/**

+ * Information on Method for the composition.

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

+ */

+public class MethodMetadata {

+

+    /**

+     * ONE POLICY.

+     */

+    public static final int ONE_POLICY = 1;

+

+    /**

+     * ALL POLICY. 

+     */

+    public static final int ALL_POLICY = 2;

+

+    /**

+     * Method Object.

+     */

+    private Method m_method;

+    

+    /**

+     * Delegation field.

+     */

+    private FieldMetadata m_delegation;

+

+    /**

+     * Delegation policy (default = ONE).

+     */

+    private int m_policy = ONE_POLICY;

+

+    /**

+     * Constructor.

+     * @param method : method object.

+     */

+    public MethodMetadata(Method method) {

+        m_method = method;

+    }

+

+    public Method getMethod() {

+        return m_method;

+    }

+

+    public void setDelegation(FieldMetadata field) {

+        m_delegation = field;

+    }

+

+    public FieldMetadata getDelegation() {

+        return m_delegation;

+    }

+    

+    /**

+     * Equals method.

+     * This method check if two MethodMetadata are equals or if the current MemethodMetadata is equals with a Method object. 

+     * @param object : object.

+     * @return true if the current object and the given object are equals.

+     * @see java.lang.Object#equals(java.lang.Object)

+     */

+    public boolean equals(Object object) {

+        if (object instanceof MethodMetadata) {

+            Method met = ((MethodMetadata) object).getMethod();

+            return equals(met);

+        }

+        

+        if (object instanceof Method) {

+            Method met = (Method) object;

+            if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {

+                return false;

+            }

+

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

+                if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {

+                    return false;

+                }

+            }

+

+            return true;

+        }

+        

+        return false;

+    }

+    

+    /**

+     * Hash code method.

+     * @return the parent hash code.

+     * @see java.lang.Object#hashCode()

+     */

+    public int hashCode() {

+        return super.hashCode();

+    }

+

+    public int getPolicy() {

+        return m_policy;

+    }

+

+    /**

+     * Activate the all policy for this method.

+     */

+    public void setAllPolicy() {

+        m_policy = ALL_POLICY;

+    }

+    

+    /**

+     * Check if the method can throw UnsupportedOperationException.

+     * @return true if the method has declared the UnsupportedOperationException.

+     */

+    protected boolean throwsUnsupportedOperationException() {

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

+            if (m_method.getExceptionTypes()[i].getName().equals(UnsupportedOperationException.class.getName())) {

+                return true;

+            }

+        }

+        return false;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
similarity index 98%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
index b8fcab7..91ed8cc 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
@@ -33,6 +33,11 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

 public class POJOWriter implements Opcodes {

+    

+    //TODO : consider using getOpCode

+    //TODO : fix bug on double-space

+    //TODO : use a logger

+    //TODO : merge this class with another class only static method.

 

     /**

      * Create a class.

@@ -168,6 +173,7 @@
                 writeReturn(Type.getReturnType(desc), mv);

             } else { // All policy

                 if (Type.getReturnType(desc).getSort() != Type.VOID) {

+                    //TODO use logger.

                     System.err.println("All policy cannot be used on method which does not return void");

                 }

 

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
new file mode 100644
index 0000000..f76aea1
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
@@ -0,0 +1,235 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.util.List;

+import java.util.Properties;

+

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

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

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

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

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

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

+import org.apache.felix.ipojo.composite.CompositeManager;

+import org.apache.felix.ipojo.composite.instance.InstanceHandler;

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+

+/**

+ * Composite Provided Service.

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

+ */

+public class ProvidedService implements DependencyStateListener {

+

+    /**

+     * Composite Manager.

+     */

+    private CompositeManager m_manager;

+

+    /**

+     * Composition Model.

+     */

+    private CompositionMetadata m_composition;

+

+    /**

+     * Internal context.

+     */

+    private ServiceContext m_scope;

+

+    /**

+     * External context.

+     */

+    private BundleContext m_context;

+

+    /**

+     * Created Factory.

+     */

+    private ComponentFactory m_factory;

+

+    /**

+     * Created Instance.

+     */

+    private ComponentInstance m_instance;

+

+    /**

+     * Exporter.

+     */

+    private ServiceExporter m_exports;

+

+    /**

+     * Created instance name.

+     */

+    private String m_instanceName;

+

+    /**

+     * Constructor.

+     * The delegation mapping is infers in this method.

+     * @param handler : the handler.

+     * @param element : 'provides' element.

+     * @param name : name of this provided service.

+     */

+    public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {

+        m_manager = handler.getCompositeManager();

+        m_scope = m_manager.getServiceContext();

+        m_context = m_manager.getContext();

+        m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);

+    }

+

+    /**

+     * Start method.

+     * Build service implementation type, factory and instance.

+     * @throws CompositionException if a consistent mapping cannot be discovered.

+     */

+    public void start() throws CompositionException {

+        m_composition.buildMapping();

+

+        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";

+        byte[] clazz = m_composition.buildPOJO();

+        Element metadata = m_composition.buildMetadata(m_instanceName);

+

+        // Create the factory

+        try {

+            m_factory = new ComponentFactory(m_context, clazz, metadata);

+        } catch (ConfigurationException e) {

+            // Should not happen.

+        }

+        m_factory.start();

+

+        try {

+            Class spec = DependencyModel.loadSpecification(m_composition.getSpecificationMetadata().getName(), m_context);

+            Filter filter = m_context.createFilter("(instance.name=" + m_instanceName + ")");

+            // Create the exports

+            m_exports = new ServiceExporter(spec, filter, false, false, null, DependencyModel.DYNAMIC_BINDING_POLICY, m_scope, m_context, this, m_manager);

+        } catch (InvalidSyntaxException e) {

+            throw new CompositionException("A provided service filter is invalid : " + e.getMessage());

+        } catch (ConfigurationException e) {

+            throw new CompositionException("The class " + m_composition.getSpecificationMetadata().getName() + " cannot be loaded : " + e.getMessage());

+        }

+    }

+

+    /**

+     * Stop the provided service.

+     * Kill the exporter, the instance and the factory.

+     */

+    public void stop() {

+        if (m_exports != null) {

+            m_exports.stop();

+            m_exports = null;

+        }

+        if (m_instance != null) {

+            m_instance.dispose();

+            m_instance = null;

+        }

+        if (m_factory != null) {

+            m_factory.stop();

+            m_factory = null;

+        }

+    }

+

+    protected CompositeManager getManager() {

+        return m_manager;

+    }

+

+    /**

+     * The exporter becomes valid.

+     * @param exporter : the exporter

+     */

+    public void validate(DependencyModel exporter) {

+        // Nothing to do.

+    }

+

+    /**

+     * The exporter becomes invalid.

+     * @param exporter : the exporter

+     */

+    public void invalidate(DependencyModel exporter) {

+        // Nothing to do.

+    }

+

+    /**

+     * Get an object from the given type.

+     * @param type : type

+     * @return an object from an instance of this type or null

+     */

+    private Object getObjectByType(String type) {

+        InstanceHandler handler = (InstanceHandler) m_manager.getCompositeHandler("org.apache.felix.ipojo.composite.instance.InstanceHandler");

+        Object pojo = handler.getObjectFromInstance(type);

+        if (pojo == null) {

+            m_manager.getFactory().getLogger().log(Logger.ERROR, "An instance object cannot be found for the type : " + type);

+        }

+        return pojo;

+    }

+

+    public String getSpecification() {

+        return m_composition.getSpecificationMetadata().getName();

+    }

+

+    /**

+     * Unregister the exposed service.

+     */

+    public void unregister() {

+        m_exports.stop();

+    }

+

+    /**

+     * Register the exposed service.

+     */

+    public void register() {

+        Properties props = new Properties();

+        props.put("name", m_instanceName);

+        List fields = m_composition.getFieldList();

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

+            FieldMetadata field = (FieldMetadata) fields.get(i);

+            if (field.isUseful() && !field.getSpecification().isInterface()) {

+                String type = field.getSpecification().getComponentType();

+                Object pojo = getObjectByType(type);

+                props.put(field.getName(), pojo);

+            }

+        }

+

+        if (m_instance == null) {

+         // Else we have to create the instance 

+            try {

+                m_instance = m_factory.createComponentInstance(props, m_manager.getServiceContext());

+            } catch (UnacceptableConfiguration e) {

+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());

+            } catch (MissingHandlerException e) {

+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());

+            } catch (ConfigurationException e) {

+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());

+            }

+        } else {

+            // We have to reconfigure the instance in order to inject up to date glue component instance.

+            m_instance.reconfigure(props);

+        }

+        

+        m_exports.start();

+    }

+

+    public boolean isRegistered() {

+        return m_exports.getState() == DependencyModel.RESOLVED;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
new file mode 100644
index 0000000..fcbec3c
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
@@ -0,0 +1,496 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.lang.reflect.Field;

+import java.util.ArrayList;

+import java.util.Comparator;

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

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

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

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

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

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

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

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

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

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

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

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

+import org.apache.felix.ipojo.composite.instance.InstanceHandler;

+import org.apache.felix.ipojo.composite.service.instantiator.ServiceDependencyHandler;

+import org.apache.felix.ipojo.composite.service.instantiator.ServiceImporter;

+import org.apache.felix.ipojo.composite.service.instantiator.SvcInstance;

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

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Composite Provided Service Handler.

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

+ */

+public class ProvidedServiceHandler extends CompositeHandler implements DependencyStateListener {

+

+    /**

+     * External context.

+     */

+    private BundleContext m_context;

+

+    /**

+     * List of "available" services in the internal context.

+     */

+    private List m_services = new ArrayList();

+

+    /**

+     * List of exporters.

+     */

+    private List m_exporters = new ArrayList();

+

+    /**

+     * List of managed services.

+     */

+    private List m_managedServices = new ArrayList();

+

+    /**

+     * List of component type.

+     */

+    private List m_types;

+

+    /**

+     * Initialize the component type.

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

+     * @param metadata : component type metadata.

+     * @throws ConfigurationException : metadata are incorrect.

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

+     */

+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {

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

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

+            String action = provides[i].getAttribute("action");

+            if (action == null) {

+                throw new ConfigurationException("Invalid composition service providing : no specified action");

+            } else if (action.equalsIgnoreCase("implement")) {

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

+                if (spec == null) {

+                    throw new ConfigurationException("Malformed provides : the specification attribute is mandatory");

+                } else {

+                    desc.addProvidedServiceSpecification(spec);

+                }

+            } else if (action.equalsIgnoreCase("export")) {

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

+                if (spec == null) {

+                    throw new ConfigurationException("Malformed exports - Missing the specification attribute");

+                } else {

+                    desc.addProvidedServiceSpecification(spec);

+                }

+            } else {

+                throw new ConfigurationException("Invalid composition service providing : unknown action " + action);

+            }

+        }

+    }

+

+    /**

+     * Configure the handler.

+     * @param metadata : the metadata of the component

+     * @param configuration : the instance configuration

+     * @throws ConfigurationException  : the exporter cannot be created

+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

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

+        m_context = getCompositeManager().getContext();

+

+        Element[] provides = metadata.getElements("provides", "");

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

+            String action = provides[i].getAttribute("action");

+            if (action.equalsIgnoreCase("implement")) {

+                ProvidedService svc = new ProvidedService(this, provides[i], Integer.toString(i));

+                m_managedServices.add(svc);

+            } else if (action.equalsIgnoreCase("export")) {

+                boolean optional = false;

+                boolean aggregate = false;

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

+

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

+

+                String opt = provides[i].getAttribute("optional");

+                optional = opt != null && opt.equalsIgnoreCase("true");

+

+                String agg = provides[i].getAttribute("aggregate");

+                aggregate = agg != null && agg.equalsIgnoreCase("true");

+

+                String givenFilter = provides[i].getAttribute("filter");

+                if (givenFilter != null) {

+                    filter = "(&" + filter + givenFilter + ")"; //NOPMD

+                }

+

+                Filter fil = null;

+                try {

+                    fil = m_context.createFilter(filter);

+                } catch (InvalidSyntaxException e) {

+                    throw new ConfigurationException("An exporter filter is invalid " + filter + " : " + e.getMessage());

+                }

+

+                Comparator cmp = DependencyModel.getComparator(provides[i], m_context);

+                int policy = DependencyModel.getPolicy(provides[i]);

+                Class spec = DependencyModel.loadSpecification(specification, m_context);

+

+                ServiceExporter imp = new ServiceExporter(spec, fil, aggregate, optional, cmp, policy, getCompositeManager().getServiceContext(), m_context, this, getCompositeManager());

+                m_exporters.add(imp);

+            } // Others case cannot happen. The test was already made during the factory initialization.

+        }

+

+    }

+

+    /**

+     * Start method.

+     * Start all managed provided service.

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

+     */

+    public void start() {

+        // Compute imports and instances

+        computeAvailableServices();

+        computeAvailableTypes();

+

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

+            ProvidedService svc = (ProvidedService) m_managedServices.get(i);

+            try {

+                checkServiceSpecification(svc);

+                svc.start();

+            } catch (CompositionException e) {

+                error("Cannot start the provided service handler", e);

+                setValidity(false);

+                return;

+            }

+        }

+

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

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

+            exp.start();

+        }

+

+        isHandlerValid();

+    }

+

+    /**

+     * Stop method.

+     * Stop all managed provided service.

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

+     */

+    public void stop() {

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

+            ProvidedService svc = (ProvidedService) m_managedServices.get(i);

+            svc.stop();

+        }

+

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

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

+            exp.stop();

+        }

+    }

+

+    /**

+     * Check the handler validity.

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

+     */

+    private void isHandlerValid() {

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

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

+            if (exp.getState() != DependencyModel.RESOLVED) {

+                setValidity(false);

+                return;

+            }

+        }

+

+        setValidity(true);

+    }

+

+    /**

+     * Handler state changed.

+     * @param state : the new instance state.

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

+     */

+    public void stateChanged(int state) {

+        if (state == ComponentInstance.INVALID) {

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

+                ProvidedService svc = (ProvidedService) m_managedServices.get(i);

+                svc.unregister();

+            }

+            return;

+        }

+

+        // If the new state is VALID => register all the services

+        if (state == ComponentInstance.VALID) {

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

+                ProvidedService svc = (ProvidedService) m_managedServices.get(i);

+                svc.register();

+            }

+            return;

+        }

+    }

+

+    /**

+     * Notify the handler that an exporter becomes invalid.

+     * 

+     * @param exporter : the implicated exporter.

+     */

+    public void invalidate(DependencyModel exporter) {

+        // An export is no more valid

+        if (getValidity()) {

+            setValidity(false);

+        }

+

+    }

+

+    /**

+     * Notify the handler that an exporter becomes valid.

+     * 

+     * @param exporter : the implicated exporter.

+     */

+    public void validate(DependencyModel exporter) {

+        // An import becomes valid

+        if (!getValidity()) {

+            isHandlerValid();

+        }

+    }

+

+    /**

+     * Build the list of available specification.

+     * @return the list of available specification.

+     */

+    protected List getSpecifications() {

+        return m_services;

+    }

+

+    /**

+     * Build the list of available specifications.

+     */

+    private void computeAvailableServices() {

+        // Get instantiated services :

+        ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");

+

+        for (int i = 0; handler != null && i < handler.getInstances().size(); i++) {

+            SvcInstance svc = (SvcInstance) handler.getInstances().get(i);

+            String itf = svc.getServiceSpecification();

+            boolean agg = svc.isAggregate();

+            boolean opt = svc.isOptional();

+

+            SpecificationMetadata specMeta = new SpecificationMetadata(itf, m_context, agg, opt, this);

+            m_services.add(specMeta);

+        }

+

+        for (int i = 0; handler != null && i < handler.getRequirements().size(); i++) {

+            ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);

+            String itf = imp.getSpecification().getName();

+            boolean agg = imp.isAggregate();

+            boolean opt = imp.isOptional();

+

+            SpecificationMetadata specMeta = new SpecificationMetadata(itf, m_context, agg, opt, this);

+            m_services.add(specMeta);

+        }

+    }

+

+    /**

+     * Check composite requirement against service specification requirement is available.

+     * @param svc : the provided service to check

+     * @throws CompositionException : occurs if the specification field of the service specification cannot be analyzed correctly.

+     */

+    private void checkServiceSpecification(ProvidedService svc) throws CompositionException {

+        try {

+            Class spec = m_context.getBundle().loadClass(svc.getSpecification());

+            Field specField = spec.getField("specification");

+            Object object = specField.get(null);

+            if (object instanceof String) {

+                Element specification = ManifestMetadataParser.parse((String) object);

+                Element[] reqs = specification.getElements("requires");

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

+                    ServiceImporter imp = getAttachedRequirement(reqs[j]);

+                    if (imp != null) {

+                        // Fix service-level dependency flag

+                        imp.setServiceLevelDependency();

+                    }

+                    checkRequirement(imp, reqs[j]);

+                }

+            } else {

+                error("[" + getCompositeManager().getInstanceName() + "] The specification field of the service specification " + svc.getSpecification() + " need to be a String");

+                throw new CompositionException("Service Specification checking failed : The specification field of the service specification " + svc.getSpecification() + " need to be a String");

+            }

+        } catch (NoSuchFieldException e) {

+            return; // No specification field

+        } catch (ClassNotFoundException e) {

+            error("[" + getCompositeManager().getInstanceName() + "] The service specification " + svc.getSpecification() + " cannot be load");

+            throw new CompositionException("The service specification " + svc.getSpecification() + " cannot be load : " + e.getMessage());

+        } catch (IllegalArgumentException e) {

+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());

+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());

+        } catch (IllegalAccessException e) {

+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());

+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());

+        } catch (ParseException e) {

+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " does not contain a valid String : " + e.getMessage());

+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " does not contain a valid String : " + e.getMessage());

+        }

+    }

+

+    /**

+     * Look for the implementation (i.e. composite) requirement for the given service-level requirement metadata.

+     * @param element : the service-level requirement metadata

+     * @return the ServiceImporter object, null if not found or if the DependencyHandler is not plugged to the instance

+     */

+    private ServiceImporter getAttachedRequirement(Element element) {

+        ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");

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

+

+        String identity = element.getAttribute("id");

+        if (identity != null) {

+            // Look for dependency Id

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

+                ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);

+                if (imp.getId().equals(identity)) { return imp; }

+            }

+        }

+

+        // If not found or no id, look for a dependency with the same specification

+        String requirement = element.getAttribute("specification");

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

+            ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);

+            if (imp.getId().equals(requirement) || imp.getSpecification().getName().equals(requirement)) { return imp; }

+        }

+        return null;

+    }

+

+    /**

+     * Check the correctness of the composite requirement against the service level dependency.

+     * @param imp : requirement to check

+     * @param elem : service-level dependency metadata

+     * @throws CompositionException : occurs if the requirement does not match with service-level specification requirement

+     */

+    private void checkRequirement(ServiceImporter imp, Element elem) throws CompositionException {

+        String optional = elem.getAttribute("optional");

+        boolean opt = optional != null && optional.equalsIgnoreCase("true");

+

+        String aggregate = elem.getAttribute("aggregate");

+        boolean agg = aggregate != null && aggregate.equalsIgnoreCase("true");

+

+        if (imp == null) {

+            // Add the missing requirement

+            ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");

+            if (handler == null) {

+                // Look for the ServiceDependencyHandler factory

+                HandlerManager handlerManager = null;

+                try {

+                    ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(&(handler.name=subservice)(handler.namespace=" + HandlerFactory.IPOJO_NAMESPACE + ")(handler.type=composite))");

+                    Factory factory = (Factory) m_context.getService(refs[0]);

+                    handlerManager = (HandlerManager) factory.createComponentInstance(null, getCompositeManager().getServiceContext());

+                } catch (InvalidSyntaxException e) {

+                    // Should not happen

+                } catch (UnacceptableConfiguration e) {

+                    // Should not happen

+                } catch (MissingHandlerException e) {

+                    // Should not happen

+                } catch (ConfigurationException e) {

+                    // Should not happen

+                }

+                

+                // Add the required handler 

+                try {

+                    handlerManager.init(getCompositeManager(), new Element("composite", ""), new Properties());

+                } catch (ConfigurationException e) {

+                    error("Internal error : cannot configure the Import Handler : " + e.getMessage());

+                    throw new CompositionException("Internal error : cannot configure the Import Handler : " + e.getMessage());

+                }

+                handler = (ServiceDependencyHandler) handlerManager.getHandler();

+                getCompositeManager().addCompositeHandler(handlerManager);

+            }

+

+            String spec = elem.getAttribute("specification");

+            String filter = "(&(objectClass=" + spec + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself

+            String givenFilter = elem.getAttribute("filter");

+            if (givenFilter != null) {

+                filter = "(&" + filter + givenFilter + ")"; //NOPMD

+            }

+

+            BundleContext context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);

+

+            Filter fil = null;

+            try {

+                fil = getCompositeManager().getGlobalContext().createFilter(filter);

+            } catch (InvalidSyntaxException e) {

+                throw new CompositionException("A required filter " + filter + " is malformed : " + e.getMessage());

+            }

+

+            Class specToImport = null;

+            try {

+                specToImport = getCompositeManager().getGlobalContext().getBundle().loadClass(spec);

+            } catch (ClassNotFoundException e) {

+                throw new CompositionException("A required specification cannot be loaded : " + spec);

+            }

+

+            ServiceImporter importer = new ServiceImporter(specToImport, fil, agg, opt, null, DependencyModel.DYNAMIC_BINDING_POLICY, context, null, handler);

+

+            handler.getRequirements().add(importer);

+            SpecificationMetadata specMeta = new SpecificationMetadata(spec, m_context, agg, opt, this);

+            m_services.add(specMeta); // Update the available types

+            return;

+        }

+

+        if (imp.isAggregate() && !agg) {

+            error("[" + getCompositeManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");

+            throw new CompositionException("The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");

+        }

+

+        String filter = elem.getAttribute("filter");

+        if (filter != null) {

+            String filter2 = imp.getFilter();

+            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {

+                error("[" + getCompositeManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");

+                throw new CompositionException("The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");

+            }

+        }

+    }

+

+    public HandlerDescription getDescription() {

+        return new ProvidedServiceHandlerDescription(this, m_managedServices, m_exporters);

+    }

+

+    /**

+     * Build available instance types.

+     */

+    private void computeAvailableTypes() {

+        InstanceHandler handler = (InstanceHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":instance");

+        if (handler == null) {

+            m_types = new ArrayList();

+        } else {

+            m_types = handler.getUsedType();

+        }

+    }

+

+    public List getInstanceType() {

+        return m_types;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
new file mode 100644
index 0000000..5c22246
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
@@ -0,0 +1,96 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.util.ArrayList;

+import java.util.List;

+

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

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

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

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

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

+

+/**

+ * Provided Service Handler Description for composite.

+ * 

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

+ */

+public class ProvidedServiceHandlerDescription extends HandlerDescription {

+

+    /**

+     * Provided Service Description list.

+     */

+    private List m_services = new ArrayList();

+    

+    /**

+     * List of exports.

+     */

+    private List m_exports;

+

+    /**

+     * Constructor.

+     * 

+     * @param handler : composite handler.

+     * @param services : The list of Provided Service.

+     * @param exporters : list of managed exports

+     */

+    public ProvidedServiceHandlerDescription(CompositeHandler handler, List services, List exporters) {

+        super(handler);

+        m_services = services;

+        m_exports = exporters;

+    }

+

+    /**

+     * Get the handler description.

+     * @return the provided service handler description

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

+     */

+    public Element getHandlerInfo() {

+        Element services = super.getHandlerInfo();

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

+            ProvidedService svc = (ProvidedService) m_services.get(i);

+            Element service = new Element("service", "");

+            String state = "unregistered";

+            if (svc.isRegistered()) {

+                state = "registered";

+            }

+            String spec = "[" + svc.getSpecification() + "]";

+            service.addAttribute(new Attribute("Specification", spec));

+            service.addAttribute(new Attribute("State", state));

+            services.addElement(service);

+        }

+        

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

+            ServiceExporter exp = (ServiceExporter) m_exports.get(i);

+            Element expo = new Element("Exports", "");

+            expo.addAttribute(new Attribute("Specification", exp.getSpecification().getName()));

+            expo.addAttribute(new Attribute("Filter", exp.getFilter()));

+            if (exp.getState() == DependencyModel.RESOLVED) {

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

+            } else {

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

+            }

+            services.addElement(expo);

+        }

+        

+        return services;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
new file mode 100644
index 0000000..38a790f
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
@@ -0,0 +1,163 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.util.Comparator;

+import java.util.Dictionary;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Properties;

+import java.util.Set;

+

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

+import org.apache.felix.ipojo.composite.CompositeManager;

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * Export an service from the scope to the parent context.

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

+ */

+public class ServiceExporter extends DependencyModel {

+

+    /**

+     * Destination context.

+     */

+    private BundleContext m_destination;

+

+    /**

+     * Composite Manager.

+     */

+    private CompositeManager m_manager;

+

+    /**

+     * Map of service reference - service registration storing exported services.

+     */

+    private Map/*<ServiceReference, ServiceRegistration>*/m_registrations = new HashMap();

+

+    /**

+     * Constructor.

+     * 

+     * @param specification : exported service specification.

+     * @param filter : LDAP filter

+     * @param multiple : is the export an aggregate export?

+     * @param optional : is the export optional?

+     * @param cmp : comparator to use in the dependency

+     * @param policy : binding policy.

+     * @param from : internal service context

+     * @param dest : parent bundle context

+     * @param listener : dependency lifecycle listener to notify when the dependency state change. 

+     * @param manager : composite manager

+     */

+    public ServiceExporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, ServiceContext from, BundleContext dest, DependencyStateListener listener, CompositeManager manager) {

+        super(specification, multiple, optional, filter, cmp, policy, from, listener);

+

+        m_destination = dest;

+

+        m_manager = manager;

+

+    }

+

+    /**

+     * Transform service reference property in a dictionary.

+     * instance.name and factory.name are injected too.

+     * @param ref : the service reference.

+     * @return the dictionary containing all property of the given service reference.

+     */

+    private Dictionary getProps(ServiceReference ref) {

+        Properties prop = new Properties();

+        String[] keys = ref.getPropertyKeys();

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

+            prop.put(keys[i], ref.getProperty(keys[i]));

+        }

+

+        prop.put("instance.name", m_manager.getInstanceName());

+        prop.put("factory.name", m_manager.getFactory().getName());

+

+        return prop;

+    }

+

+    /**

+     * Stop an exporter.

+     * Remove the service listener

+     * Unregister all exported services.

+     */

+    public void stop() {

+        super.stop();

+        Set refs = m_registrations.keySet();

+        Iterator iterator = refs.iterator();

+        while (iterator.hasNext()) {

+            ServiceReference ref = (ServiceReference) iterator.next();

+            ServiceRegistration reg = (ServiceRegistration) m_registrations.get(ref);

+            reg.unregister();

+        }

+        m_registrations.clear();

+    }

+

+    /**

+     * A service has been injected. Register it.

+     * @param reference : the new reference.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

+     */

+    public void onServiceArrival(ServiceReference reference) {

+        Object svc = getService(reference);

+        ServiceRegistration reg = m_destination.registerService(getSpecification().getName(), svc, getProps(reference));

+        m_registrations.put(reference, reg);

+    }

+

+    /**

+     * An exported service was modified.

+     * @param reference : modified reference

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void onServiceModification(ServiceReference reference) {

+        ServiceRegistration reg = (ServiceRegistration) m_registrations.get(reference);

+        if (reg != null) {

+            reg.setProperties(getProps(reference));

+        }

+    }

+

+    /**

+     * An exported service disappears.

+     * @param reference : service reference

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void onServiceDeparture(ServiceReference reference) {

+        ServiceRegistration reg = (ServiceRegistration) m_registrations.get(reference);

+        if (reg != null) {

+            reg.unregister();

+        }

+        m_registrations.remove(reference);

+    }

+

+    /**

+     * On Dependency Reconfiguration notification method.

+     * @param departs : leaving service references.

+     * @param arrivals : new injected service references.

+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])

+     */

+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {

+        throw new UnsupportedOperationException("Dynamic dependency reconfiguration is not supported by service exporter");

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
similarity index 85%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
rename to ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
index 6ccf87b..392de87 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
@@ -1,161 +1,158 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-
-/**
- * Represent a service specification.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class SpecificationMetadata {
-
-    /**
-     * Name of the specification, i.e. name of the interface.
-     */
-    private String m_name;
-
-    /**
-     * List of the method contained in the specification.
-     */
-    private List/* <MethodMetadata> */m_methods = new ArrayList/* <MethodMetadata> */();
-
-    /**
-     * Is the specification an aggregate?
-     */
-    private boolean m_isAggregate;
-
-    /**
-     * Is the specification optional?
-     */
-    private boolean m_isOptional = false;
-    
-    /**
-     * Is the specification an interface?
-     */
-    private boolean m_isInterface = true;
-    
-    /**
-     * Component Type.
-     */
-    private String m_componentType = null;
-
-    /**
-     * Reference on the handler.
-     */
-    private ProvidedServiceHandler m_handler;
-
-    /**
-     * Constructor.
-     * @param name : specification name.
-     * @param bc : bundle context.
-     * @param isAggregate : is the specification aggregate.
-     * @param isOptional : is the specification optional.
-     * @param psd : the handler.
-     */
-    public SpecificationMetadata(String name, BundleContext bc, boolean isAggregate, boolean isOptional, ProvidedServiceHandler psd) {
-        m_name = name;
-        m_handler = psd;
-    
-        // Populate methods :
-        try {
-            Class clazz = bc.getBundle().loadClass(name);
-            Method[] methods = clazz.getMethods();
-            for (int i = 0; i < methods.length; i++) {
-                MethodMetadata method = new MethodMetadata(methods[i]);
-                m_methods.add(method);
-            }
-        } catch (ClassNotFoundException e) {
-            m_handler.log(Logger.ERROR, "Cannot open " + name + " : " + e.getMessage());
-            return;
-        }
-    
-        m_isAggregate = isAggregate;
-        m_isOptional = isOptional;
-    }
-
-    /**
-     * Constructor.
-     * @param c : class
-     * @param type : component type
-     * @param psd : the parent handler
-     */
-    public SpecificationMetadata(Class c, String type, ProvidedServiceHandler psd) {
-        m_handler = psd;
-        m_isAggregate = false;
-        m_isOptional = false;
-        m_componentType = type;
-        m_name = c.getName();
-        Method[] methods = c.getMethods();
-        for (int i = 0; i < methods.length; i++) {
-            MethodMetadata method = new MethodMetadata(methods[i]);    
-            m_methods.add(method);
-        }
-        m_isInterface = false;
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public List/* <MethodMetadata> */getMethods() {
-        return m_methods;
-    }
-
-    /**
-     * Get a method by its name.
-     * @param name : method name
-     * @return the method metadata contained in the current specification with the given name. Null if the method is not found.
-     */
-    public MethodMetadata getMethodByName(String name) {
-        for (int i = 0; i < m_methods.size(); i++) {
-            MethodMetadata met = (MethodMetadata) m_methods.get(i);
-            if (met.getMethod().getName().equals(name)) {
-                return met;
-            }
-        }
-        return null;
-    }
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-    
-    public boolean isInterface() {
-        return m_isInterface;
-    }
-
-    public void setIsOptional(boolean optional) {
-        m_isOptional = optional;
-    }
-    
-    public String getComponentType() {
-        return m_componentType;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.service.provides;

+

+import java.lang.reflect.Method;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.osgi.framework.BundleContext;

+

+/**

+ * Represent a service specification.

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

+ */

+public class SpecificationMetadata {

+

+    /**

+     * Name of the specification, i.e. name of the interface.

+     */

+    private String m_name;

+

+    /**

+     * List of the method contained in the specification.

+     */

+    private List/* <MethodMetadata> */m_methods = new ArrayList/* <MethodMetadata> */();

+

+    /**

+     * Is the specification an aggregate?

+     */

+    private boolean m_isAggregate;

+

+    /**

+     * Is the specification optional?

+     */

+    private boolean m_isOptional = false;

+

+    /**

+     * Is the specification an interface?

+     */

+    private boolean m_isInterface = true;

+

+    /**

+     * Component Type.

+     */

+    private String m_componentType = null;

+

+    /**

+     * Reference on the handler.

+     */

+    private ProvidedServiceHandler m_handler;

+

+    /**

+     * Constructor.

+     * @param name : specification name.

+     * @param context : bundle context.

+     * @param isAggregate : is the specification aggregate.

+     * @param isOptional : is the specification optional.

+     * @param psd : the handler.

+     */

+    public SpecificationMetadata(String name, BundleContext context, boolean isAggregate, boolean isOptional, ProvidedServiceHandler psd) {

+        m_name = name;

+        m_handler = psd;

+

+        // Populate methods :

+        try {

+            Class clazz = context.getBundle().loadClass(name);

+            Method[] methods = clazz.getMethods();

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

+                MethodMetadata method = new MethodMetadata(methods[i]);

+                m_methods.add(method);

+            }

+        } catch (ClassNotFoundException e) {

+            m_handler.error("Cannot open " + name + " : " + e.getMessage());

+            return;

+        }

+

+        m_isAggregate = isAggregate;

+        m_isOptional = isOptional;

+    }

+

+    /**

+     * Constructor.

+     * @param clazz : class

+     * @param type : component type

+     * @param psd : the parent handler

+     */

+    public SpecificationMetadata(Class clazz, String type, ProvidedServiceHandler psd) {

+        m_handler = psd;

+        m_isAggregate = false;

+        m_isOptional = false;

+        m_componentType = type;

+        m_name = clazz.getName();

+        Method[] methods = clazz.getMethods();

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

+            MethodMetadata method = new MethodMetadata(methods[i]);

+            m_methods.add(method);

+        }

+        m_isInterface = false;

+    }

+

+    public String getName() {

+        return m_name;

+    }

+

+    public List/* <MethodMetadata> */getMethods() {

+        return m_methods;

+    }

+

+    /**

+     * Get a method by its name.

+     * @param name : method name

+     * @return the method metadata contained in the current specification with the given name. Null if the method is not found.

+     */

+    public MethodMetadata getMethodByName(String name) {

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

+            MethodMetadata met = (MethodMetadata) m_methods.get(i);

+            if (met.getMethod().getName().equals(name)) { return met; }

+        }

+        return null;

+    }

+

+    public boolean isAggregate() {

+        return m_isAggregate;

+    }

+

+    public boolean isOptional() {

+        return m_isOptional;

+    }

+

+    public boolean isInterface() {

+        return m_isInterface;

+    }

+

+    public void setIsOptional(boolean optional) {

+        m_isOptional = optional;

+    }

+

+    public String getComponentType() {

+        return m_componentType;

+    }

+

+}

diff --git a/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java
new file mode 100644
index 0000000..d7f227a
--- /dev/null
+++ b/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java
@@ -0,0 +1,376 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.composite.util;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

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

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

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

+import org.apache.felix.ipojo.composite.CompositeManager;

+import org.apache.felix.ipojo.parser.ParseUtils;

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * This class manages context-source management.

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

+ */

+public class SourceManager implements ContextListener {

+

+    /**

+     * Source Name service property.

+     */

+    public static final String SOURCE_NAME = "source.name";

+

+    /**

+     * Managed dependency.

+     */

+    private DependencyModel m_dependency;

+

+    /**

+     * List of monitored context sources.

+     */

+    private List/* <ContextSource> */m_sources = new ArrayList(1);

+

+    /**

+     * PRoperties contained in the original filter.

+     */

+    private String[] m_properties;

+

+    /**

+     * Original filter (containing variables). 

+     */

+    private String m_filter;

+

+    /**

+     * Bundle context.

+     */

+    private BundleContext m_context;

+

+    /**

+     * Service Tracker List.

+     */

+    private List/*<SourceTracker>*/m_trackers = new ArrayList(1);

+

+    /**

+     * Constructor.

+     * @param sources : context-source attribute from the dependency metadata

+     * @param depfilter : original dependency filter

+     * @param dependency : dependency object

+     * @param manager : composite manager

+     * @throws ConfigurationException : the sources are incorrect.

+     */

+    public SourceManager(String sources, String depfilter, DependencyModel dependency, CompositeManager manager) throws ConfigurationException {

+        m_filter = depfilter;

+        m_properties = getProperties(depfilter);

+        m_dependency = dependency;

+        m_context = manager.getGlobalContext();

+        if (manager.getParentServiceContext() == null) {

+            // The parent is the global context

+            parseSources(sources, manager.getGlobalContext(), manager.getGlobalContext(), manager.getServiceContext());

+        } else {

+            parseSources(sources, manager.getGlobalContext(), manager.getParentServiceContext(), manager.getServiceContext());

+        }

+    }

+

+    /**

+     * Start the context management.

+     */

+    public void start() {

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

+            ((SourceTracker) m_trackers.get(i)).open();

+        }

+        computeFilter();

+    }

+

+    /**

+     * Stop the context management.

+     */

+    public void stop() {

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

+            ((SourceTracker) m_trackers.get(i)).close();

+        }

+        setFilter(m_filter);

+        m_sources.clear();

+    }

+

+    /**

+     * Get the state of this source manager.

+     * @return the state of this source manager.

+     */

+    public int getState() {

+        if (m_sources.isEmpty()) {

+            return DependencyModel.UNRESOLVED;

+        } else {

+            return DependencyModel.RESOLVED;

+        }

+    }

+

+    /**

+     * Set the filter of the managed dependency.

+     * @param filter : the new filter to apply

+     */

+    private void setFilter(String filter) {

+        if (!filter.equals(m_dependency.getFilter())) {

+            // Reconfigure

+            try {

+                m_dependency.setFilter(m_context.createFilter(filter));

+            } catch (InvalidSyntaxException e) {

+                throw new IllegalStateException("A context filter is invalid : " + filter);

+            }

+        }

+    }

+

+    /**

+     * Compute the new filter.

+     */

+    private void computeFilter() {

+        String fil = m_filter;

+        synchronized (this) {

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

+                Dictionary props = ((ContextSource) m_sources.get(i)).getContext();

+                fil = substitute(fil, props); //NOPMD

+            }

+        }

+        if (!fil.equals(m_dependency.getFilter())) {

+            setFilter(fil);

+        }

+    }

+

+    /**

+     * This method substitute ${var} substring by values stored in a map.

+     * @param str : string with variables

+     * @param values : dictionary containing the variable name and the value.

+     * @return resulted string

+     */

+    public static String substitute(String str, Dictionary values) {       

+        int len = str.length();

+        StringBuffer buffer = new StringBuffer(len);

+

+        int prev = 0;

+        int start = str.indexOf("${");

+        int end = str.indexOf('}', start);

+        while (start != -1 && end != -1) {

+            String key = str.substring(start + 2, end);

+            Object value = values.get(key);

+            if (value == null) {

+                buffer.append(str.substring(prev, end + 1));

+            } else {

+                buffer.append(str.substring(prev, start));

+                buffer.append(value);

+            }

+            prev = end + 1;

+            if (prev >= str.length()) {

+                break;

+            }

+

+            start = str.indexOf("${", prev);

+            if (start != -1) {

+                end = str.indexOf('}', start);

+            }

+        }

+

+        buffer.append(str.substring(prev));

+

+        return buffer.toString();

+    }

+

+    /**

+     * Compute the properties (${name}) from the given filter.

+     * @param str : string form of the filter.

+     * @return the list of found properties.

+     */

+    public static String[] getProperties(String str) {

+        List list = new ArrayList();

+        int prev = 0;

+        int start = str.indexOf("${");

+        int end = str.indexOf('}', start);

+        while (start != -1 && end != -1) {

+            String key = str.substring(start + 2, end);

+            list.add(key);

+            prev = end + 1;

+            if (prev >= str.length()) {

+                break;

+            }

+

+            start = str.indexOf("${", prev);

+            if (start != -1) {

+                end = str.indexOf('}', start);

+            }

+        }

+

+        return (String[]) list.toArray(new String[list.size()]);

+    }

+

+    /**

+     * A context source has modified a monitored property. 

+     * @param source : source

+     * @param property : modified property

+     * @param value : new value.

+     * @see org.apache.felix.ipojo.ContextListener#update(org.apache.felix.ipojo.ContextSource, java.lang.String, java.lang.Object)

+     */

+    public synchronized void update(ContextSource source, String property, Object value) {

+        computeFilter();

+    }

+

+    /**

+     * Parse the context-source attribute in order to create source tracker object.

+     * @param sourceAtt : context-source attribute.

+     * @param global : global bundle context.

+     * @param parent : parent bundle context.

+     * @param local : local bundle context.

+     * @throws ConfigurationException : the context-source attribute is invalid.

+     */

+    private void parseSources(String sourceAtt, BundleContext global, BundleContext parent, BundleContext local) throws ConfigurationException {

+        String[] sources = ParseUtils.split(sourceAtt, ",");

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

+            String[] srcs = ParseUtils.split(sources[i], ":");

+            if (srcs.length == 1) {

+                // No prefix use local. //TODO choose default case.

+                SourceTracker tracker = new SourceTracker(srcs[0], local);

+                m_trackers.add(tracker);

+            } else if (srcs.length == 2) {

+                // According to prefix add the source in the good list.

+                if (srcs[0].equalsIgnoreCase("parent")) {

+                    SourceTracker tracker = new SourceTracker(srcs[1], parent);

+                    m_trackers.add(tracker);

+                } else if (srcs[0].equalsIgnoreCase("local")) {

+                    SourceTracker tracker = new SourceTracker(srcs[1], local);

+                    m_trackers.add(tracker);

+                } else if (srcs[0].equalsIgnoreCase("global")) {

+                    SourceTracker tracker = new SourceTracker(srcs[1], global);

+                    m_trackers.add(tracker);

+                } else {

+                    throw new ConfigurationException("Unknowns context scope : " + srcs[0]);

+                }

+            } else {

+                throw new ConfigurationException("Malformed context source : " + sources[i]);

+            }

+        }

+    }

+

+    /**

+     * A context source appears.

+     * @param source : new context source.

+     */

+    private void addContextSource(ContextSource source) {

+        m_sources.add(source);

+        computeFilter();

+        source.registerContextListener(this, m_properties);

+    }

+

+    /**

+     * A context source disappears.

+     * @param source : leaving context source.

+     */

+    private void removeContextSource(ContextSource source) {

+        m_sources.remove(source);

+        computeFilter();

+    }

+

+    private class SourceTracker implements TrackerCustomizer {

+

+        /**

+         * Service tracker.

+         */

+        private Tracker m_tracker;

+

+        /**

+         * Constructor.

+         * @param name : name of the required context-source.

+         * @param countext : bundle context to use.

+         * @throws ConfigurationException : the context-source name is invalid.

+         */

+        public SourceTracker(String name, BundleContext countext) throws ConfigurationException {

+            String fil = "(&(" + Constants.OBJECTCLASS + "=" + ContextSource.class.getName() + ")(" + SOURCE_NAME + "=" + name + "))";

+            try {

+                Filter filter = countext.createFilter(fil);

+                m_tracker = new Tracker(countext, filter, this);

+            } catch (InvalidSyntaxException e) {

+                throw new ConfigurationException("A Context source filter is invalid " + fil + " : " + e.getMessage());

+            }

+        }

+

+        /**

+         * Open the tracker.

+         */

+        public void open() {

+            m_tracker.open();

+        }

+

+        /**

+         * Close the tracker.

+         */

+        public void close() {

+            m_tracker.close();

+        }

+

+        /**

+         * A new context-source was added.

+         * This method inject the context-source object in the source manager.

+         * @param reference : service reference.

+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

+         */

+        public void addedService(ServiceReference reference) {

+            addContextSource((ContextSource) m_tracker.getService(reference));

+        }

+

+        /**

+         * A new context-source is adding in the tracker.. 

+         * @param reference : service reference

+         * @return true.

+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+         */

+        public boolean addingService(ServiceReference reference) {

+            return true;

+        }

+

+        /**

+         * A used context-source is modified.

+         * @param reference : service reference.

+         * @param service : service object.

+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+         */

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

+            // Nothing to do.

+        }

+

+        /**

+         * A used context-source disappears.

+         * This method notify the Source Manager in order to manage this departure. 

+         * @param reference : service reference.

+         * @param service : service object.

+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+         */

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

+            removeContextSource((ContextSource) service);

+        }

+

+    }

+

+}

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

+	<!-- Composite Handler -->

+	<handler

+		classname="org.apache.felix.ipojo.composite.instance.InstanceHandler"

+		name="instance" type="composite" architecture="false" level="1">

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

+			optional="true">

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

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

+		</requires>

+	</handler>

+	<handler

+		classname="org.apache.felix.ipojo.composite.service.instantiator.ServiceDependencyHandler"

+		name="subservice" type="composite" architecture="false">

+	</handler>

+	<handler

+		classname="org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler"

+		name="provides" type="composite" architecture="false" level="3">

+	</handler>

+	<handler

+		classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler"

+		name="architecture" type="composite" architecture="false">

+		<provides>

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

+		</provides>

+	</handler>

+</ipojo>
\ No newline at end of file
diff --git a/ipojo/core/pom.xml b/ipojo/core/pom.xml
index 813548b..c7ef593 100644
--- a/ipojo/core/pom.xml
+++ b/ipojo/core/pom.xml
@@ -1,118 +1,125 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
 -->
 <project>
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix</artifactId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <name>Apache Felix iPOJO</name>
-  <artifactId>org.apache.felix.ipojo</artifactId>
-  <version>0.7.5-SNAPSHOT</version>
-  <dependencies>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <version>1.1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <version>1.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.0</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>          
-            <Bundle-Name>iPOJO</Bundle-Name>
-            <Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
-            <Bundle-Description> iPOJO </Bundle-Description>
-            <Bundle-Activator>org.apache.felix.ipojo.Extender</Bundle-Activator>
-            <Import-Package>
-              org.osgi.framework, 
-              org.osgi.service.cm,
-              org.osgi.service.log,
-			  !org.objectweb.asm*
-            </Import-Package>
-            <Private-Package>
-            	org.apache.felix.ipojo.manipulation,
-    			org.apache.felix.ipojo.composite.architecture,
-    			org.apache.felix.ipojo.composite.service*,
-    			org.apache.felix.ipojo.composite.instance,
-    			org.apache.felix.ipojo.handlers.architecture,
-    			org.apache.felix.ipojo.handlers.configuration,
-    			org.apache.felix.ipojo.handlers.dependency.nullable,
-              	org.apache.felix.ipojo.handlers.lifecycle.callback,
-              	org.apache.felix.ipojo.handlers.lifecycle.controller,
-              	org.objectweb.asm*;-split-package:=merge-first
-            </Private-Package>
-            <Export-Package>
-              org.apache.felix.ipojo; version="0.7.5", 
-              org.apache.felix.ipojo.metadata; version="0.7.5", 
-              org.apache.felix.ipojo.architecture; version="0.7.5", 
-              org.apache.felix.ipojo.parser; version="0.7.5",
-              org.apache.felix.ipojo.util; version="0.7.5",
-              org.apache.felix.ipojo.handlers.dependency; version="0.7.5",
-              org.apache.felix.ipojo.handlers.providedservice; version="0.7.5", 
-              org.apache.felix.ipojo.composite; version="0.7.5",
-              org.osgi.service.cm,
-              org.osgi.service.log
-            </Export-Package>
-            <_donotcopy>(CVS|.svn|.+.bak|~.+|metadata.xml)</_donotcopy>
-          </instructions>
-        </configuration>
-      </plugin>
-       <plugin>
-	      <groupId>org.apache.felix</groupId>
-	      <artifactId>maven-ipojo-plugin</artifactId>
-              <version>${pom.version}</version>
-		  <executions>
-          	<execution>
-            	<goals>
-	              <goal>ipojo-bundle</goal>
-               </goals>
-            <configuration>
-   				<metadata>metadata.xml</metadata>
-   				<ignoreAnnotations>true</ignoreAnnotations>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
+	<parent>
+		<artifactId>iPOJO</artifactId>
+		<groupId>org.apache.felix</groupId>
+		<version>0.7.6-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<packaging>bundle</packaging>
+	<name>Apache Felix iPOJO</name>
+	<artifactId>org.apache.felix.ipojo</artifactId>
+	<dependencies>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.osgi.compendium</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>
+			<version>0.7.6-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+			<version>0.7.6-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>1.4.0</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Name>iPOJO</Bundle-Name>
+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
+						<Bundle-Description>
+							iPOJO Core Framework
+						</Bundle-Description>
+						<Bundle-Activator>
+							org.apache.felix.ipojo.Extender
+						</Bundle-Activator>
+						<IPOJO-Extension>
+							component:org.apache.felix.ipojo.ComponentFactory,
+							handler:org.apache.felix.ipojo.HandlerFactory
+						</IPOJO-Extension>
+						<Import-Package>
+							org.osgi.framework, org.osgi.service.cm,
+							org.osgi.service.log
+						</Import-Package>
+						<Private-Package>
+							org.apache.felix.ipojo.handlers.architecture,
+							org.apache.felix.ipojo.handlers.configuration,
+							org.apache.felix.ipojo.handlers.lifecycle.callback,
+							org.apache.felix.ipojo.handlers.lifecycle.controller
+						</Private-Package>
+						<Export-Package>
+							org.apache.felix.ipojo; version="0.7.6",
+							org.apache.felix.ipojo.metadata;
+							version="0.7.6",
+							org.apache.felix.ipojo.architecture;
+							version="0.7.6",
+							org.apache.felix.ipojo.parser;
+							version="0.7.6",
+							org.apache.felix.ipojo.util;
+							version="0.7.6",
+							org.apache.felix.ipojo.handlers.dependency;
+							version="0.7.6",
+							org.apache.felix.ipojo.handlers.providedservice;
+							version="0.7.6",
+							org.apache.felix.ipojo.context;
+							version="0.7.6", org.osgi.service.cm,
+							org.osgi.service.log
+						</Export-Package>
+						<_donotcopy>
+							(CVS|.svn|.+.bak|~.+|metadata.xml)
+						</_donotcopy>
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-ipojo-plugin</artifactId>
+				<version>${pom.version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>ipojo-bundle</goal>
+						</goals>
+						<configuration>
+							<metadata>metadata.xml</metadata>
+							<ignoreAnnotations>true</ignoreAnnotations>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
 </project>
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index d5ff230..1c62ecf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -21,27 +21,22 @@
 import java.net.URL;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 import org.apache.felix.ipojo.util.Logger;
 import org.apache.felix.ipojo.util.Tracker;
 import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
 
 /**
  * The component factory manages component instance objects. This management
@@ -50,379 +45,114 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ComponentFactory implements Factory, ManagedServiceFactory, TrackerCustomizer {
-
-    /**
-     * List of the managed instance name. This list is shared by all factories.
-     */
-    protected static List m_instancesName = new ArrayList();
-    
-    /**
-     * Component-Type description exposed by the factory service.
-     */
-    protected ComponentDescription m_componentDesc;
-    
-    /**
-     * List of the managed instance managers. The key of this map is the
-     * name (i.e. instance names) of the created instance
-     */
-    protected Map m_componentInstances = new HashMap();
-    
-    /**
-     * Component Type provided by this factory.
-     */
-    protected Element m_componentMetadata;
-    
-    /**
-     * The bundle context reference.
-     */
-    protected BundleContext m_context = null;    
-    
-    /**
-     * Factory Name. Could be the component class name if the
-     * factory name is not set.
-     */
-    protected String m_factoryName;
-
-    /**
-     * List of required handler.
-     */
-    protected List m_handlerIdentifiers = new ArrayList();
-
-    /**
-     * List of listeners.
-     */
-    protected List m_listeners = new ArrayList(5);
-    
-    /**
-     * Logger for the factory (and all component instance).
-     */
-    protected Logger m_logger;
-
-    /**
-     * Factory state.
-     */
-    protected int m_state = Factory.INVALID;
+public class ComponentFactory extends IPojoFactory implements TrackerCustomizer {
 
     /**
      * Tracker used to track required handler factories.
      */
     protected Tracker m_tracker;
-    
-    /**
-     * Is the factory public (expose as a service). 
-     */
-    protected boolean m_isPublic;
 
     /**
      * Class loader to delegate loading.
      */
     private FactoryClassloader m_classLoader = null;
-    
+
     /**
      * Component Implementation class.
      */
     private byte[] m_clazz = null;
-    
+
     /**
      * Component Implementation Class Name.
      */
-    private String m_componentClassName = null;
-    
+    private String m_classname = null;
+
     /**
-     * Index used to generate instance name if not set.
+     * Manipulation Metadata of the internal POJO.
      */
-    private long m_index = 0;
-    
-    /**
-     * Service Registration of this factory (Factory & ManagedServiceFactory).
-     */
-    private ServiceRegistration m_sr;
-    
+    private PojoMetadata m_manipulation = null;
+
     /**
      * Create a instance manager factory. The class is given in parameter. The
      * component type is not a composite.
-     * @param bc : bundle context
+     * @param context : bundle context
      * @param clazz : the component class
-     * @param cm : metadata of the component
+     * @param element : metadata of the component
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public ComponentFactory(BundleContext bc, byte[] clazz, Element cm) {
-        this(bc, cm);
+    public ComponentFactory(BundleContext context, byte[] clazz, Element element) throws ConfigurationException {
+        this(context, element);
         m_clazz = clazz;
     }
-    
-    /**
-     * Create a instance manager factory.
-     * @param bc : bundle context
-     * @param cm : metadata of the component to create
-     */
-    public ComponentFactory(BundleContext bc, Element cm) {
-        m_context = bc;
-        m_componentMetadata = cm;
-        
-        if (! check(cm)) {
-            return;
-        }
-        
-        computeFactoryName();        
-        m_logger = new Logger(m_context, m_factoryName, Logger.WARNING);
-        
-        String fac = cm.getAttribute("factory");
-        m_isPublic = fac == null || ! fac.equalsIgnoreCase("false");
-        
-        computeRequiredHandlers();
-        
-    }
-    
-    /**
-     * Add a factory listener.
-     * @param l : the factory listener to add
-     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
-     */
-    public void addFactoryStateListener(FactoryStateListener l) {
-        synchronized (m_listeners) {
-            m_listeners.add(l);
-        }
-        // TODO do we need to notify the actual state of the factory to the new listener ?
-    }
 
     /**
-     * A new handler factory is detected.
-     * Test if the factory can be used or not.
-     * @param reference : the new service reference.
-     * @return true if the given factory reference match with a required handler.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     * Create a instance manager factory.
+     * @param context : bundle context
+     * @param element : metadata of the component to create
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public boolean addingService(ServiceReference reference) {
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            if (hi.m_reference == null && match(hi, reference)) {
-                int oldP = hi.m_level;
-                hi.setReference(reference);
-                // If the priority has changed, sort the list.
-                if (oldP != hi.m_level) {
-                    Collections.sort(m_handlerIdentifiers);
-                }
-                return true;
-            }
-        }
-        return false;
+    public ComponentFactory(BundleContext context, Element element) throws ConfigurationException {
+        super(context, element);
+        check(element); // NOPMD. This invocation is normal.
     }
-    
-    /**
-     * A matching service has been added to the tracker, we can no compute the factory state.
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        if (m_state == INVALID) {
-            try {
-                computeFactoryState();
-            } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-                stop();
-            }
-        }
+
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new PrimitiveTypeDescription(this);
     }
 
     /**
      * Check method : allow a factory to check if given element are correct.
      * A component factory metadata are correct if they contain the 'classname' attribute.
-     * @param cm : the metadata
-     * @return true if the metadata are correct
+     * @param element : the metadata
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
      */
-    public boolean check(Element cm) {
-        m_componentClassName = cm.getAttribute("className");
-        if (m_componentClassName == null) {
-            System.err.println("A component needs a class name : " + cm);
-            return false;
-        } else {
-            return true;
-        }
+    public void check(Element element) throws ConfigurationException {
+        m_classname = element.getAttribute("className");
+        if (m_classname == null) { throw new ConfigurationException("A component needs a class name : " + element); }
+    }
+
+    public String getClassName() {
+        return m_classname;
     }
 
     /**
-     * Create an instance. The given configuration needs to contain the 'name'
-     * property.
-     * @param configuration : configuration of the created instance.
-     * @return the created component instance.
-     * @throws UnacceptableConfiguration : occurs if the given configuration is
-     * not consistent with the component type of this factory.
-     * @throws MissingHandlerException  : occurs if an handler is unavailable when the instance is created.
-     * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the instance or type configuration are not correct.
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     * Create a primitive instance.
+     * @param config : instance configuration
+     * @param context : service context.
+     * @param handlers : handler to use
+     * @return the created instance
+     * @throws org.apache.felix.ipojo.ConfigurationException : if the configuration process failed.
+     * @see org.apache.felix.ipojo.IPojoFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {
-        return createComponentInstance(configuration, null);
-    }
-    
-    /**
-     * Create an instance. The given configuration needs to contain the 'name'
-     * property.
-     * @param configuration : configuration of the created instance.
-     * @param serviceContext : the service context to push for this instance.
-     * @return the created component instance.
-     * @throws UnacceptableConfiguration : occurs if the given configuration is
-     * not consistent with the component type of this factory.
-     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.
-     * @throws org.apache.felix.ipojo.ConfigurationException : when the instance configuration failed.
-     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
-     */
-    public synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, org.apache.felix.ipojo.ConfigurationException {        
-        if (configuration == null) {
-            configuration = new Properties();
-        }
-        
+    public ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers) throws org.apache.felix.ipojo.ConfigurationException {
+        InstanceManager instance = new InstanceManager(this, context, handlers);
+        instance.configure(m_componentMetadata, config);
         try {
-            checkAcceptability(configuration);
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-            throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage());
+            instance.start();
+            return instance;
+        } catch (IllegalStateException e) {
+            // An exception occurs during the start method.
+            m_logger.log(Logger.ERROR, e.getMessage(), e);
+            throw new ConfigurationException(e.getMessage());
         }
 
-        
-        String n = null;
-        if (configuration.get("name") != null) {
-            n = (String) configuration.get("name");
-            if (m_instancesName.contains(n)) {
-                throw new UnacceptableConfiguration("Name already used : " + n);
-            }
-        } else {
-            n = generateName();
-            configuration.put("name", n);
-        }
-        m_instancesName.add(n);
-
-        BundleContext context = null;
-        if (serviceContext == null) {
-            context = new IPojoContext(m_context);
-        } else {
-            context = new IPojoContext(m_context, serviceContext);
-        }
-        
-        List handlers = new ArrayList();
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            handlers.add(getHandlerInstance(hi, serviceContext));
-        }
-        
-        InstanceManager instance = new InstanceManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[m_handlerIdentifiers.size()]));
-        try {
-            instance.configure(m_componentMetadata, configuration);
-        } catch (org.apache.felix.ipojo.ConfigurationException e) {
-            throw new org.apache.felix.ipojo.ConfigurationException(e.getMessage(), m_factoryName);
-        }
-
-        m_componentInstances.put(n, instance);
-        instance.start();
-
-        return instance;
     }
 
     /**
      * Define a class.
      * @param name : qualified name of the class
-     * @param b : byte array of the class
+     * @param clazz : byte array of the class
      * @param domain : protection domain of the class
      * @return the defined class object
      */
-    public Class defineClass(String name, byte[] b, ProtectionDomain domain) {
+    public Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
         if (m_classLoader == null) {
             m_classLoader = new FactoryClassloader();
         }
-        return m_classLoader.defineClass(name, b, domain);
-    }
-    
-    /**
-     * Delete an instance.
-     * @param in : name of the instance to delete
-     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
-     */
-    public synchronized void deleted(String in) {
-        m_instancesName.remove(in);
-        final ComponentInstance cm = (ComponentInstance) m_componentInstances.remove(in);
-        if (cm == null) {
-            return; // do nothing, the component does not exist !
-        } else {
-            cm.dispose();
-        }
+        return m_classLoader.defineClass(name, clazz, domain);
     }
 
     /**
-     * Get the component type description.
-     * @return the component type description object. Null if not already computed.
-     */
-    public ComponentDescription getComponentDescription() {
-        return m_componentDesc;
-    }
-
-    /**
-     * Get the component type description attached to this factory.
-     * @return : the component type description
-     * @see org.apache.felix.ipojo.Factory#getDescription()
-     */
-    public Element getDescription() {
-        if (m_componentDesc == null) { return new Element("No description available for " + m_factoryName, ""); }
-        return m_componentDesc.getDescription();
-    }
-    
-    /**
-     * Get the logger used by instances of he current factory.
-     * @return the factory logger.
-     */
-    public Logger getLogger() {
-        return m_logger;
-    }
-    
-    /**
-     * Get the list of missing handlers.
-     * @return the list of missing handlers (namespace:name)
-     * @see org.apache.felix.ipojo.Factory#getMissingHandlers()
-     */
-    public List getMissingHandlers() {
-        List l = new ArrayList();
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            if (hi.m_reference == null) {
-                l.add(hi.getFullName());
-            }
-        }
-        return l;
-    }
-
-    /**
-     * Get the name of this factory.
-     * 
-     * @return the name of this factory
-     * @see org.apache.felix.ipojo.Factory#getName()
-     */
-    public String getName() {
-        return m_factoryName;
-    }
-
-    /**
-     * Get the list of required handlers.
-     * @return the list of required handlers (namespace:name)
-     * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
-     */
-    public List getRequiredHandlers() {
-        List l = new ArrayList();
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            l.add(hi.getFullName());
-        }
-        return l;
-    }
-    
-    public String getClassName() {
-        return m_componentClassName;
-    }
-
-    public int getState() {
-        return m_state;
-    }
-    
-    /**
      * Return the URL of a resource.
      * @param resName : resource name
      * @return the URL of the resource
@@ -432,24 +162,6 @@
     }
 
     /**
-     * Check if the given configuration is acceptable as a component instance
-     * configuration. This method checks that if all the configurable properties
-     * have a value.
-     * @param conf : the configuration to check
-     * @return true when the configuration seems to be acceptable
-     */
-    public boolean isAcceptable(Dictionary conf) {
-        try {
-            checkAcceptability(conf);
-        } catch (UnacceptableConfiguration e) { 
-            return false; 
-        } catch (MissingHandlerException e) { 
-            return false;  
-        }
-        return true;
-    }
-
-    /**
      * Load a class.
      * @param className : name of the class to load
      * @return the resulting Class object
@@ -457,22 +169,144 @@
      * @throws ClassNotFoundException : happen when the class is not found
      */
     public Class loadClass(String className) throws ClassNotFoundException {
-        if (m_clazz != null && className.equals(m_componentClassName)) {
+        if (m_clazz != null && className.equals(m_classname)) {
             // Used the factory classloader to load the component implementation
             // class
             if (m_classLoader == null) {
                 m_classLoader = new FactoryClassloader();
             }
-            try {
-                return m_classLoader.defineClass(m_componentClassName, m_clazz, null);
-            } catch (Exception e) {
-                throw new ClassNotFoundException("[Bundle " + m_context.getBundle().getBundleId() + "] Cannot define the class : " + className, e);
-            }
+            return m_classLoader.defineClass(m_classname, m_clazz, null);
         }
         return m_context.getBundle().loadClass(className);
     }
 
     /**
+     * Start the factory.
+     */
+    public synchronized void starting() {
+        if (m_requiredHandlers.size() != 0) {
+            try {
+                String filter = "(&(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" + "(factory.state=1)" + ")";
+                m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+                m_tracker.open();
+            } catch (InvalidSyntaxException e) {
+                m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());
+                stop();
+            }
+        }
+    }
+
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stopping() {
+        m_tracker.close();
+        m_tracker = null;
+        m_classLoader = null;
+        m_clazz = null;
+    }
+
+    /**
+     * Compute the factory name.
+     * @return the factory name.
+     */
+    public String getFactoryName() {
+        String name = m_componentMetadata.getAttribute("name");
+        if (name == null) { // No factory name, try with factory attribute
+            name = m_componentMetadata.getAttribute("factory");
+            if (name == null || name.equalsIgnoreCase("true") || name.equalsIgnoreCase("false")) { // Avoid boolean case
+                name = m_componentMetadata.getAttribute("className");
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Compute required handlers.
+     * @return the required handler list.
+     */
+    public List getRequiredHandlerList() {
+        List list = new ArrayList();
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i];
+            if (!"manipulation".equals(current.getName())) {
+                RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());
+                if (!list.contains(req)) {
+                    list.add(req);
+                }
+            }
+        }
+
+        // Add architecture if architecture != 'false'
+        String arch = m_componentMetadata.getAttribute("architecture");
+        if (arch == null || arch.equalsIgnoreCase("true")) {
+            list.add(new RequiredHandler("architecture", null));
+        }
+
+        // Add lifecycle callback if immediate = true
+        RequiredHandler reqCallback = new RequiredHandler("callback", null);
+        String imm = m_componentMetadata.getAttribute("immediate");
+        if (!list.contains(reqCallback) && imm != null && imm.equalsIgnoreCase("true")) {
+            list.add(reqCallback);
+        }
+
+        return list;
+    }
+
+    /**
+     * A new handler factory is detected.
+     * Test if the factory can be used or not.
+     * @param reference : the new service reference.
+     * @return true if the given factory reference match with a required handler.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null && match(req, reference)) {
+                int oldP = req.getLevel();
+                req.setReference(reference);
+                // If the priority has changed, sort the list.
+                if (oldP != req.getLevel()) {
+                    Collections.sort(m_requiredHandlers);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * A matching service has been added to the tracker, we can no compute the factory state.
+     * @param reference : added reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        if (m_state == INVALID) {
+            computeFactoryState();
+        }
+    }
+
+    /**
+     * A used factory disappears.
+     * @param reference : service reference.
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        // Look for the implied reference and invalid the handler identifier
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (reference.equals(req.getReference())) {
+                req.unRef(); // This method will unget the service.
+                computeFactoryState();
+                return; // The factory can be used only once.
+            }
+        }
+    }
+
+    /**
      * A used handler factory is modified.
      * @param reference : the service reference
      * @param service : the Factory object (if already get)
@@ -483,561 +317,15 @@
     }
 
     /**
-     * Reconfigure an existing instance.
-     * @param properties : the new configuration to push.
-     * @throws UnacceptableConfiguration : occurs if the new configuration is
-     * not consistent with the component type.
-     * @throws MissingHandlerException : occurs if the current factory is not valid.
-     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     * Returns manipulation metadata of this component type.
+     * The returned object is computed at the first call and then is cached.
+     * @return manipulation metadata of this component type.
      */
-    public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {
-        if (properties == null || properties.get("name") == null) {
-            throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property");
+    public PojoMetadata getPojoMetadata() {
+        if (m_manipulation == null) {
+            m_manipulation = new PojoMetadata(m_componentMetadata);
         }
-        final String name = (String) properties.get("name");
-        InstanceManager cm = (InstanceManager) m_componentInstances.get(name);
-        
-        if (cm == null) {
-            return; // The instance does not exist.
-        } else {
-            checkAcceptability(properties); // Test if the configuration is acceptable
-            cm.reconfigure(properties); // re-configure the component
-        }
-    }
-
-    /**
-     * A used factory disappears.
-     * @param reference : service reference.
-     * @param service : factory object.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-        // Look for the implied reference and invalid the handler identifier
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            if (reference.equals(hi.getReference())) {
-                hi.unRef(); // This method will unget the service.
-                try {
-                    computeFactoryState();
-                } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                    m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-                    stop();
-                }
-                return; // The factory can be used only once.
-            }
-        }
-    }
-
-    /**
-     * Remove a factory listener.
-     * @param l : the factory listener to remove
-     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
-     */
-    public void removeFactoryStateListener(FactoryStateListener l) {
-        synchronized (m_listeners) {
-            m_listeners.remove(l);
-        }
-    }
-
-    /**
-     * Start the factory.
-     */
-    public synchronized void start() {
-        if (m_componentDesc != null) { // Already started.
-            return;
-        } 
-        
-        if (m_handlerIdentifiers.size() != 0) {
-            try {
-                String filter = "(&(" + Constants.OBJECTCLASS + "=" + Factory.class.getName() + ")"
-                        + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" 
-                        + "(factory.state=1)"
-                        + ")";
-                m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
-                m_tracker.open();
-            } catch (InvalidSyntaxException e) {
-                m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());
-                stop();
-                return;
-            }
-        }
-            
-        try {
-            computeFactoryState();
-        } catch (org.apache.felix.ipojo.ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The component type metadata are not correct : " + e.getMessage());
-            stop();
-            return;
-        }
-
-        if (m_isPublic) {        
-            // Exposition of the factory service
-            m_sr = m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, getProperties());
-        }
-    }
-
-    /**
-     * Stop all the instance managers.
-     */
-    public synchronized void stop() {
-        if (m_sr != null) {
-            m_sr.unregister();
-            m_sr = null;
-        }
-        
-        if (m_tracker != null) {        
-            m_tracker.close();
-        }
-        
-        final Collection col = m_componentInstances.values();
-        final Iterator it = col.iterator();
-        while (it.hasNext()) {
-            InstanceManager ci = (InstanceManager) it.next();
-            if (ci.getState() != ComponentInstance.DISPOSED) {
-                ci.kill();
-            }
-            m_instancesName.remove(ci.getInstanceName());
-        }
-        
-        m_componentInstances.clear();
-        
-        // Release each handler
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            ((HandlerIdentifier) m_handlerIdentifiers.get(i)).unRef();
-        }
-        
-        m_tracker = null;
-        m_componentDesc = null;
-        m_classLoader = null;
-        m_clazz = null;
-        m_state = INVALID;
-    }
-    
-    /**
-     * Create of update an instance.
-     * @param in : name of the instance
-     * @param properties : configuration of the instance
-     * @throws ConfigurationException : if the configuration is not consistent
-     * for this component type
-     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String,
-     * java.util.Dictionary)
-     */
-    public synchronized void updated(String in, Dictionary properties) throws ConfigurationException {
-        final InstanceManager cm = (InstanceManager) m_componentInstances.get(in);
-        if (cm == null) {
-            try {
-                properties.put("name", in); // Add the name in the configuration
-                createComponentInstance(properties);
-            } catch (UnacceptableConfiguration e) {
-                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            } catch (MissingHandlerException e) {
-                m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                m_logger.log(Logger.ERROR, "The Component Type metadata are not correct : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            }
-        } else {
-            try {
-                properties.put("name", in); // Add the name in the configuration
-                reconfigure(properties); // re-configure the component
-            } catch (UnacceptableConfiguration e) {
-                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            } catch (MissingHandlerException e) {
-                m_logger.log(Logger.ERROR, "The facotry is not valid, at least one handler is missing : " + e.getMessage());
-                throw new ConfigurationException(properties.toString(), e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * Test is a configuration is acceptable for the factory.
-     * @param conf : the configuration to test.
-     * @throws UnacceptableConfiguration : the configuration is not acceptable.
-     * @throws MissingHandlerException : the factory is not valid.
-     */
-    protected void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
-        if (m_state == Factory.INVALID) {
-            throw new MissingHandlerException(getMissingHandlers());
-        }
-        
-        List props = m_componentDesc.getRequiredProperties();
-        for (int i = 0; i < props.size(); i++) {
-            // Failed if the props has no default value and the configuration does not push a value
-            if (conf.get(props.get(i)) == null) {
-                throw new UnacceptableConfiguration("The configuration does not contains the \"" + props.get(i) + "\" property");
-            }
-        }
-    }
-    
-    /**
-     * Compute the component type description.
-     * The factory must be valid when calling this method.
-     * @throws org.apache.felix.ipojo.ConfigurationException if one handler has rejected the configuration.
-     */
-    protected void computeDescription() throws org.apache.felix.ipojo.ConfigurationException {
-        m_componentDesc = new ComponentDescription(this);
-         
-        for (int i = 0; i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            HandlerManager hm = getHandlerInstance(hi, null);
-            Handler ch =  hm.getHandler();
-            try {
-                ch.setLogger(getLogger());
-                ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);
-                ((Pojo) ch).getComponentInstance().dispose();
-            } catch (org.apache.felix.ipojo.ConfigurationException e) {
-                ((Pojo) ch).getComponentInstance().dispose();
-                throw new org.apache.felix.ipojo.ConfigurationException(e.getMessage(), m_factoryName);
-            }
-        }
-    }
-
-    /**
-     * Compute the factory name.
-     */
-    protected void computeFactoryName() {
-        m_factoryName = m_componentMetadata.getAttribute("name");
-        if (m_factoryName == null) { // No factory name, try with factory attribute
-            m_factoryName = m_componentMetadata.getAttribute("factory");
-            if (m_factoryName == null || m_factoryName.equalsIgnoreCase("true") || m_factoryName.equalsIgnoreCase("false")) { // Avoid boolean case
-                m_factoryName = m_componentMetadata.getAttribute("className");
-            }
-        }
-    }
-    
-    /**
-     * Compute factory state.
-     * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the component type cannot be initialize.
-     */
-    protected void computeFactoryState() throws org.apache.felix.ipojo.ConfigurationException {
-        boolean isValid = true;
-        for (int i = 0; isValid && i < m_handlerIdentifiers.size(); i++) {
-            HandlerIdentifier hi = (HandlerIdentifier) m_handlerIdentifiers.get(i);
-            isValid = hi.m_reference != null;
-        }
-        
-        if (isValid) {
-            if (m_state == INVALID) {
-                
-                if (m_componentDesc == null) {
-                    computeDescription();
-                }
-                
-                m_state = VALID;
-                if (m_sr != null) {
-                    m_sr.setProperties(getProperties());
-                }
-                for (int i = 0; i < m_listeners.size(); i++) {
-                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
-                }
-                return;
-            }
-        } else {
-            if (m_state == VALID) {
-                m_state = INVALID;
-                
-                // Notify listeners.
-                for (int i = 0; i < m_listeners.size(); i++) {
-                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
-                }
-
-                // Dispose created instances.
-                final Collection col = m_componentInstances.values();
-                final Iterator it = col.iterator();
-                while (it.hasNext()) {
-                    InstanceManager ci = (InstanceManager) it.next();
-                    if (ci.getState() != ComponentInstance.DISPOSED) {
-                        ci.kill();
-                    }
-                    m_instancesName.remove(ci.m_name);
-                }
-
-                m_componentInstances.clear();
-
-                // Update service properties TODO : really useful ?
-                if (m_sr != null) {
-                    m_sr.setProperties(getProperties());
-                }
-                
-                return;
-            }
-        }
-    }
-    
-    /**
-     * Compute required handlers.
-     */
-    protected void computeRequiredHandlers() {
-        Element[] elems = m_componentMetadata.getElements();
-        for (int i = 0; i < elems.length; i++) {
-            Element current = elems[i]; 
-            if (current.getName().equals("manipulation")) { continue; }
-            HandlerIdentifier hi = new HandlerIdentifier(current.getName(), current.getNameSpace());
-            if (! m_handlerIdentifiers.contains(hi)) { m_handlerIdentifiers.add(hi); }
-        }
-        
-        // Add architecture if architecture != 'false'
-        HandlerIdentifier hi = new HandlerIdentifier("architecture", null);
-        String arch = m_componentMetadata.getAttribute("architecture");
-        if (arch == null || arch.equalsIgnoreCase("true")) {
-            m_handlerIdentifiers.add(hi);
-        }
-        
-        // Add lifecycle callback if immediate = true
-        HandlerIdentifier hi2 = new HandlerIdentifier("callback", null);
-        String imm = m_componentMetadata.getAttribute("immediate");
-        if (! m_handlerIdentifiers.contains(hi2) && imm != null && imm.equalsIgnoreCase("true")) {
-            m_handlerIdentifiers.add(hi2);
-        }
-    }
-
-    /**
-     * Callback called by instance when disposed.
-     * @param ci : the destroyed instance
-     */
-    protected void disposed(ComponentInstance ci) {
-        String name = ci.getInstanceName();
-        m_instancesName.remove(name);
-        m_componentInstances.remove(name);
-    }
-    
-    /**
-     * Generate an instance name.
-     * @return an non already used name
-     */
-    protected synchronized String generateName() {
-        String name = m_factoryName + "-" + m_index;
-        while (m_instancesName.contains(name)) {
-            m_index = m_index + 1;
-            name = m_factoryName + "-" + m_index;
-        }
-        return name;
-    }
-    
-    /**
-     * Return the bundle context.
-     * @return the Bundle Context.
-     */
-    public BundleContext getBundleContext() {
-        return m_context;
-    }
-
-    /**
-     * Get the implementation class of the component type.
-     * 
-     * @return the name of the component-type implementation class.
-     */
-    protected String getComponentClassName() {
-        return m_componentClassName;
-    }
-
-    /**
-     * Compute factory properties.
-     * @return the properties.
-     */
-    protected Properties getProperties() {
-        final Properties props = new Properties();
-
-        props.put("component.class", m_componentClassName);
-       
-        props.put("factory.name", m_factoryName);
-        props.put(Constants.SERVICE_PID, m_factoryName); // Service PID is required for the integration in the configuration admin.
-        
-        if (m_componentDesc != null) {
-            props.put("component.providedServiceSpecifications", m_componentDesc.getprovidedServiceSpecification());
-            props.put("component.properties", m_componentDesc.getProperties());
-            props.put("component.description", m_componentDesc);
-        }
-        
-        // Add factory state
-        props.put("factory.state", "" + m_state);
-        
-        return props;
-    }
-    
-    /**
-     * Check if the given handler identifier and the service reference can match.
-     * @param hi : the handler identifier.
-     * @param ref : the service reference.
-     * @return true if the service reference can fulfill the handler requirement
-     */
-    protected boolean match(HandlerIdentifier hi, ServiceReference ref) {
-        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
-        String ns = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
-        if (IPojoConfiguration.IPOJO_NAMESPACE.equals(ns)) {
-            return name.equals(hi.m_name) && hi.m_namespace == null;
-        }
-        return name.equals(hi.m_name) && ns.equals(hi.m_namespace); 
-    }
-
-    /**
-     * Return an handler object.
-     * @param hi : handler to create.
-     * @param sc : service context in which create the handler (instance context).
-     * @return the Handler object.
-     */
-    private HandlerManager getHandlerInstance(HandlerIdentifier hi, ServiceContext sc) {
-        try {
-            return (HandlerManager) hi.getFactory().createComponentInstance(null, sc);
-        } catch (MissingHandlerException e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed: " + e.getMessage());
-            stop();
-            return null;
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "The creation of the handler " + hi.getFullName() + " has failed (UnacceptableConfiguration): " + e.getMessage());
-            stop();
-            return null;
-        } catch (org.apache.felix.ipojo.ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The configuration of the handler " + hi.getFullName() + " has failed (ConfigurationException): " + e.getMessage());
-            stop();
-            return null;
-        }
-    }
-
-    /**
-     * Structure storing required handlers.
-     */
-    class HandlerIdentifier implements Comparable {
-        /**
-         * Factory to create this handler.
-         */
-        private HandlerFactory m_factory;
-        
-        /**
-         * Handler name.
-         */
-        private String m_name;
-        
-        /**
-         * Handler start level.
-         */
-        private int m_level = Integer.MAX_VALUE;
-        
-        /**
-         * Handler namespace.
-         */
-        private String m_namespace;
-        
-        /**
-         * Service Reference of the handler factory.
-         */
-        private ServiceReference m_reference;
-        
-        /**
-         * Constructor.
-         * @param n : handler name.
-         * @param ns : handler namespace.
-         */
-        public HandlerIdentifier(String n, String ns) {
-            m_name = n;
-            m_namespace = ns;
-        }
-        
-        /**
-         * Equals method.
-         * Two handlers are equals if they have same name and namespace or they share the same service reference.
-         * @param o : object to compare to the current object.
-         * @return : true if the two compared object are equals
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        public boolean equals(Object o) {
-            if (m_namespace == null) {
-                return ((HandlerIdentifier) o).m_name.equalsIgnoreCase(m_name) && ((HandlerIdentifier) o).m_namespace == null;
-            } else {
-                return ((HandlerIdentifier) o).m_name.equalsIgnoreCase(m_name) && m_namespace.equalsIgnoreCase(((HandlerIdentifier) o).m_namespace);
-            }
-        }
-        
-        /**
-         * Get the factory object used for this handler.
-         * The object is get when used for the first time.
-         * @return the factory object.
-         */
-        public HandlerFactory getFactory() {
-            if (m_reference == null) {
-                return null;
-            }
-            if (m_factory == null) {
-                m_factory = (HandlerFactory) m_tracker.getService(getReference());
-            }
-            return m_factory;
-        }
-        
-        /**
-         * Get the handler full name (namespace:name).
-         * @return the handler full name
-         */
-        public String getFullName() {
-            if (m_namespace == null) {
-                return IPojoConfiguration.IPOJO_NAMESPACE + ":" + m_name;
-            } else {
-                return m_namespace + ":" + m_name;
-            }
-        }
-        
-        public String getName() {
-            return m_name;
-        }
-        
-        public String getNamespace() {
-            return m_namespace;
-        }
-        
-        public ServiceReference getReference() {
-            return m_reference;
-        }
-        
-        public int getLevel() {
-            return m_level;
-        }
-        
-        /**
-         * Release the reference of the used factory.
-         */
-        public void unRef() {
-            if (m_reference != null) {
-                m_tracker.ungetService(m_reference);
-                m_factory = null;
-                m_reference = null;
-            }
-        }
-        
-        /**
-         * Set the service reference.
-         * If the new service reference is null, it unget the used factory (if already get).
-         * @param ref : new service reference.
-         */
-        public void setReference(ServiceReference ref) {            
-            m_reference = ref;
-            Integer p = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);
-            if (p != null) {
-                m_level = p.intValue();
-            }
-        }
-
-        /**
-         * Start level Comparison.
-         * This method is used to sort the handler array.
-         * @param o : object on which compare.
-         * @return -1, 0, +1 according to the comparison of their start level.
-         * @see java.lang.Comparable#compareTo(java.lang.Object)
-         */
-        public int compareTo(Object o) {
-            if (o instanceof HandlerIdentifier) {
-                HandlerIdentifier hi = (HandlerIdentifier) o;
-                if (this.m_level == hi.m_level) {
-                    return 0;
-                } else if (this.m_level < hi.m_level) {
-                    return -1;
-                } else {
-                    return +1;
-                }
-            }
-            return 0;
-        }
+        return m_manipulation;
     }
 
     /**
@@ -1048,22 +336,20 @@
         /**
          * Map of defined classes [Name, Class Object].
          */
-        private Map m_definedClasses = new HashMap();
+        private final Map m_definedClasses = new HashMap();
 
         /**
          * The defineClass method.
          * @param name : name of the class
-         * @param b : the byte array of the class
+         * @param clazz : the byte array of the class
          * @param domain : the protection domain
          * @return : the defined class.
          */
-        public Class defineClass(String name, byte[] b, ProtectionDomain domain) {
-            if (m_definedClasses.containsKey(name)) {
-                return (Class) m_definedClasses.get(name);
-            }
-            final Class c = super.defineClass(name, b, 0, b.length, domain);
-            m_definedClasses.put(name, c);
-            return c;
+        public Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+            if (m_definedClasses.containsKey(name)) { return (Class) m_definedClasses.get(name); }
+            Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
+            m_definedClasses.put(name, clas);
+            return clas;
         }
 
         /**
@@ -1084,8 +370,44 @@
          * @return : the loaded class
          * @throws ClassNotFoundException : the class to load is not found
          */
-        protected Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
             return m_context.getBundle().loadClass(name);
         }
     }
+
+    private final class PrimitiveTypeDescription extends ComponentTypeDescription {
+
+        /**
+         * Constructor.
+         * @param factory : the represented factory.
+         */
+        public PrimitiveTypeDescription(Factory factory) {
+            super(factory);
+        }
+
+        /**
+         * Compute the properties to publish : 
+         * component.class contains the pojo class name.
+         * @return the dictionary of properties to publish
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+         */
+        public Dictionary getPropertiesToPublish() {
+            Dictionary dict = super.getPropertiesToPublish();
+            if (m_classname != null) {
+                dict.put("component.class", m_classname);
+            }
+            return dict;
+        }
+
+        /**
+         * Add the "implementation-class" attribute to the type description.
+         * @return the component type description.
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getDescription()
+         */
+        public Element getDescription() {
+            Element elem = super.getDescription();
+            elem.addAttribute(new Attribute("Implementation-Class", m_classname));
+            return elem;
+        }
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
deleted file mode 100644
index a87015e..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/CompositeFactory.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.ipojo;

-

-import java.util.ArrayList;

-import java.util.Collection;

-import java.util.Dictionary;

-import java.util.Iterator;

-import java.util.List;

-import java.util.Properties;

-

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

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

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

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

-import org.osgi.framework.BundleContext;

-import org.osgi.framework.Constants;

-import org.osgi.framework.InvalidSyntaxException;

-import org.osgi.framework.ServiceReference;

-import org.osgi.framework.ServiceRegistration;

-

-/**

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

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

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

- * 

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

- */

-public class CompositeFactory extends ComponentFactory implements Factory {

-

-    /**

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

-     */

-    private ServiceRegistration m_sr;

-

-    /**

-     * Create a composite factory.

-     * @param bc : bundle context

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

-     */

-    public CompositeFactory(BundleContext bc, Element cm) {

-        super(bc, cm);

-    }

-    

-    /**

-     * Check if the metadata are well formed.

-     * @param cm : metadata

-     * @return true if the metadata are correct.

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

-     */

-    public boolean check(Element cm) {

-        m_factoryName = cm.getAttribute("name");

-        if (m_factoryName == null) {

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

-            return false;

-        } else {

-            return true;

-        }

-    }

-    

-    /**

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

-     * @param hi : handler identifier.

-     * @param ref : service reference.

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

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

-     */

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

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

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

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

-        

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

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

-                return name.equals(hi.getName()) && hi.getNamespace() == null;

-            }

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

-        } else {

-            return false;

-        }

-    }

-        

-    

-    /**

-     * Compute required handlers.

-     */

-    protected void computeRequiredHandlers() {

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

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

-            Element current = elems[i]; 

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

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

-        }

-        

-        // Add architecture if architecture != 'false'

-        String arch = m_componentMetadata.getAttribute("architecture");

-        if (arch == null || arch.equalsIgnoreCase("true")) {

-            HandlerIdentifier hi = new HandlerIdentifier("architecture", null);

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

-        }

-    }

-    

-    /**

-     * Stop all the instance managers.

-     */

-    public synchronized void stop() {

-        if (m_tracker != null) {

-            m_tracker.close();

-        }

-        

-        final Collection col = m_componentInstances.values();

-        final Iterator it = col.iterator();

-        while (it.hasNext()) {

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

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

-                ci.kill();

-            }

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

-        }

-        

-        m_componentInstances.clear();

-        if (m_sr != null) { 

-            m_sr.unregister();

-            m_sr = null;

-        }

-        m_tracker = null;

-        m_componentDesc = null;

-        m_state = INVALID;

-    }

-

-    /**

-     * Start all the instance managers.

-     */

-    public synchronized void start() {

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

-            return;

-        } 

-        if (m_handlerIdentifiers.size() != 0) {

-            try {

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

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

-                    + "(factory.state=1)"

-                    + ")";

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

-                m_tracker.open();

-            } catch (InvalidSyntaxException e) {

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

-                stop();

-                return;

-            }

-        }

-

-        try {

-            computeFactoryState();

-        } catch (ConfigurationException e) {

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

-            stop();

-            return;

-        }

-        

-        // Check if the factory should be exposed

-        if (m_isPublic) {

-            // Exposition of the factory service

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

-        }

-    }

-    

-    

-    /**

-     * Compute factory service properties.

-     * @return the factory service properties

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

-     */

-    protected Properties getProperties() {

-        final Properties props = new Properties();

-        

-        if (m_componentDesc != null) {

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

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

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

-        }

-        

-        // Add factory state

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

-        

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

-        

-        return props;

-    }

-    

-    public String getClassName() {

-        return "composite";

-    }

-

-

-    /**

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

-     * property.

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

-     * @return the created component instance.

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

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

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

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

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

-     */

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

-        return createComponentInstance(configuration, null);

-    }

-

-    /**

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

-     * property.

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

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

-     * @return the created component instance.

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

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

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

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

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

-     */

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

-        if (configuration == null) {

-            configuration = new Properties();

-        }

-        

-        try {

-            checkAcceptability(configuration);

-        } catch (UnacceptableConfiguration e) {

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

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

-        }

-

-        

-        String in = null;

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

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

-        } else {

-            in = generateName();

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

-        }

-        

-        if (m_instancesName.contains(in)) {

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

-        } else {

-            m_instancesName.add(in);

-        }

-

-        BundleContext context = null;

-        if (serviceContext == null) {

-            context = new IPojoContext(m_context);

-        } else {

-            context = new IPojoContext(m_context, serviceContext);

-        }

-        ComponentInstance instance = null;

-        List handlers = new ArrayList();

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

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

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

-        }

-       

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

-        inst.configure(m_componentMetadata, configuration);

-        instance = inst;

-

-        m_componentInstances.put(in, instance);

-        instance.start();

-        return instance;

-    }

-

-    /**

-     * Reconfigure an existing instance.

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

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

-     * not consistent with the component type.

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

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

-     */

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

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

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

-        }

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

-        

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

-        

-        if (cm == null) {

-            return; // The instance does not exist.

-        }

-        

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

-    }

-    

-    /**

-     * Compute factory state.

-     * @throws ConfigurationException : occurs if the component type cannot be initialized correctly.

-     */

-    protected void computeFactoryState() throws ConfigurationException {

-        boolean isValid = true;

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

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

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

-        }

-

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

-            computeDescription();

-        }

-

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

-            m_state = VALID;

-            if (m_sr != null) {

-                m_sr.setProperties(getProperties());

-            }

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

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

-            }

-            return;

-        }

-

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

-            m_state = INVALID;

-

-            final Collection col = m_componentInstances.values();

-            final Iterator it = col.iterator();

-            while (it.hasNext()) {

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

-                ci.kill();

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

-            }

-

-            m_componentInstances.clear();

-

-            if (m_sr != null) {

-                m_sr.setProperties(getProperties());

-            }

-

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

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

-            }

-            return;

-        }

-

-    }

-

-    /**

-     * Compute component type description.

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

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

-     */

-    public void computeDescription() throws ConfigurationException {

-        List l = new ArrayList();

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

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

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

-        }

-        

-        m_componentDesc = new ComponentDescription(this);

-       

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

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

-            HandlerManager hm = getHandlerInstance(hi, null);

-            hm.getHandler();

-            Handler ch =  hm.getHandler();

-            ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);

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

-        }

-    }

-    

-    /**

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

-     * @param handler : the handler identifier.

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

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

-     */

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

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

-        try {

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

-        } catch (MissingHandlerException e) {

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

-            stop();

-            return null;

-        } catch (UnacceptableConfiguration e) {

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

-            stop();

-            return null;

-        } catch (ConfigurationException e) {

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

-            stop();

-            return null;

-        }

-    }

-}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
index 90c9ba4..cde3140 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
@@ -29,11 +29,6 @@
      * Serialization Id.

      */

     private static final long serialVersionUID = 1L;

-

-    /**

-     * Message.

-     */

-    private String m_message;

     

     /**

      * Component Type on which the error occurs.

@@ -46,8 +41,8 @@
      * @param typ : component type

      */

     ConfigurationException(String mes, String typ) {

+        super(mes);

         m_type = typ;

-        m_message = mes;

     }

     

     /**

@@ -55,7 +50,7 @@
      * @param mes : message

      */

     public ConfigurationException(String mes) {

-        m_message = mes;

+        super(mes);

     }

     

     /**

@@ -64,10 +59,10 @@
      * @see java.lang.Throwable#getMessage()

      */

     public String getMessage() {

-        if (m_type != null) {

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

+        if (m_type == null) {

+            return super.getMessage();

         } else {

-            return m_message;

+            return "The configuration is not correct for the type " + m_type + " : " + super.getMessage();

         }

     }

 

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

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+

+/**

+ * Context Source Listener.

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

+ */

+public interface ContextListener {

+    

+    /**

+     * A monitored value has been modified.

+     * @param source : context source containing the property

+     * @param property : modified property name

+     * @param value : new value of the property

+     */

+    void update(ContextSource source, String property, Object value);

+

+}

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

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+import java.util.Dictionary;

+

+

+/**

+ * Context Source service interface.

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

+ */

+public interface ContextSource {

+    

+    /**

+     * Get the current value of the given property.

+     * @param property : property name

+     * @return the property value, null if unknown

+     */

+    Object getProperty(String property);

+    

+    /**

+     * Get the whole context.

+     * @return the dictionary [Property, Value]

+     */

+    Dictionary getContext();

+    

+    /**

+     * Register a context listener on the given set of properties.

+     * The listener will be notified of every change made on these properties.

+     * @param listener : the context listener to register.

+     * @param properties : property set monitored by the listener.

+     */

+    void registerContextListener(ContextListener listener, String[] properties);

+    

+    /**

+     * Unregister the given context listener.

+     * @param listener : the listener to unregister.

+     */

+    void unregisterContextListener(ContextListener listener);

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
index aeb4c0f..fd9ab38 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
@@ -19,20 +19,27 @@
 package org.apache.felix.ipojo;

 

 import java.io.IOException;

+import java.lang.reflect.Constructor;

+import java.lang.reflect.Field;

+import java.lang.reflect.InvocationTargetException;

+import java.lang.reflect.Method;

+import java.util.ArrayList;

 import java.util.Dictionary;

-import java.util.Enumeration;

-import java.util.Hashtable;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

 

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

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

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

+import org.apache.felix.ipojo.parser.ParseUtils;

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

 import org.osgi.framework.Bundle;

 import org.osgi.framework.BundleActivator;

 import org.osgi.framework.BundleContext;

 import org.osgi.framework.BundleEvent;

-import org.osgi.framework.ServiceReference;

 import org.osgi.framework.SynchronousBundleListener;

-import org.osgi.service.log.LogService;

 

 /**

  * iPOJO Extender.

@@ -42,39 +49,52 @@
 public class Extender implements SynchronousBundleListener, BundleActivator {

 

     /**

-     * iPOJO Manifest header.

+     * iPOJO Component Type and Instance declaration header.

      */

     private static final String IPOJO_HEADER = "iPOJO-Components";

-    

+

+    /**

+     * iPOJO Extension declaration header. 

+     */

+    private static final String IPOJO_EXTENSION = "IPOJO-Extension";

+

+    /**

+     * iPOJO Extender logger.

+     */

+    private Logger m_logger;

+

     /**

      * iPOJO Bundle Context.

      */

     private BundleContext m_context;

-    

+

     /**

-     * Dictionary of [BundleId, Factory List]. 

+     * Declared instance manager.

      */

-    private Dictionary m_components;

-    

+    private InstanceCreator m_creator;

+

     /**

-     * Dictionary of [BundleId, Instance Creator]. 

+     * iPOJO Bundle.

      */

-    private Dictionary m_creators;

-    

+    private Bundle m_bundle;

+

     /**

-     * iPOJO Bundle Id.

+     * List of factory types.

      */

-    private long m_bundleId;

-    

+    private List m_factoryTypes = new ArrayList();

+

+    /**

+     * List of unbound types.

+     */

+    private final List m_unboundTypes = new ArrayList();

+

     /**

      * Bundle Listener Notification.

      * @param event : the bundle event.

      * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)

      */

     public synchronized void bundleChanged(BundleEvent event) {

-        if (event.getBundle().getBundleId() == m_bundleId) {

-            return;

-        }

+        if (event.getBundle() == m_bundle) { return; }

 

         switch (event.getType()) {

             case BundleEvent.STARTED:

@@ -83,7 +103,7 @@
             case BundleEvent.STOPPING:

                 closeManagementFor(event.getBundle());

                 break;

-            default: 

+            default:

                 break;

         }

 

@@ -94,42 +114,109 @@
      * @param bundle : the bundle.

      */

     private void closeManagementFor(Bundle bundle) {

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

-        InstanceCreator creator = (InstanceCreator) m_creators.get(bundle);

-        if (cfs == null && creator == null) { return; }

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

-            ComponentFactory factory = cfs[i];

-            factory.stop();

+        List toRemove = new ArrayList();

+        for (int k = 0; k < m_factoryTypes.size(); k++) {

+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);

+

+            // Delete instances declared in the leaving bundle.

+            m_creator.removeInstancesFromBundle(bundle.getBundleId());

+

+            // Look for component type created from this bundle.

+            if (mft.m_created != null) {

+                List cfs = (List) mft.m_created.remove(bundle);

+                for (int i = 0; cfs != null && i < cfs.size(); i++) {

+                    IPojoFactory factory = (IPojoFactory) cfs.get(i);

+                    m_creator.removeFactory(factory);

+                    factory.stop();

+                }

+            }

+

+            // If the leaving bundle has declared mft : destroy all created factories.

+            if (mft.m_bundle == bundle) {

+                if (mft.m_created != null) {

+                    Iterator iterator = mft.m_created.keySet().iterator();

+                    while (iterator.hasNext()) {

+                        Bundle key = (Bundle) iterator.next();

+                        List list = (List) mft.m_created.get(key);

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

+                            IPojoFactory factory = (IPojoFactory) list.get(i);

+                            factory.stop();

+                            m_unboundTypes.add(new UnboundComponentType(mft.m_type, factory.m_componentMetadata, factory.getBundleContext()

+                                    .getBundle()));

+                        }

+                    }

+                }

+                toRemove.add(mft);

+            }

         }

-        if (creator != null) { creator.stop(); }

-        

-        m_components.remove(bundle);

-        m_creators.remove(bundle);

-        

+

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

+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) toRemove.get(i);

+            m_logger.log(Logger.WARNING, "The factory type available: " + mft.m_type + " is no more available");

+            mft.m_bundle = null;

+            mft.m_clazz = null;

+            mft.m_created = null;

+            mft.m_type = null;

+            m_factoryTypes.remove(mft);

+        }

     }

 

     /**

-     * Check if the given bundle is an iPOJO bundle, and begin the iPOJO management is true. 

+     * Check if the given bundle is an iPOJO bundle, and begin the iPOJO management is true.

      * @param bundle : the bundle to check.

      */

     private void startManagementFor(Bundle bundle) {

-        // Check bundle

         Dictionary dict = bundle.getHeaders();

+        // Check for abstract factory type

+        String typeHeader = (String) dict.get(IPOJO_EXTENSION);

+        if (typeHeader != null) {

+            parseAbstractFactoryType(bundle, typeHeader);

+        }

+

+        // Check bundle

         String header = (String) dict.get(IPOJO_HEADER);

-        if (header == null) {

-            return;

-        } else {

+        if (header != null) {

             try {

                 parse(bundle, header);

             } catch (IOException e) {

-                err("An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);

+                m_logger.log(Logger.ERROR, "An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);

             } catch (ParseException e) {

-                err("A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);

+                m_logger.log(Logger.ERROR, "A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);

             }

         }

-        

     }

-    

+

+    /**

+     * Parse an IPOJO-Extension manifest header.

+     * @param bundle : bundle containing the header.

+     * @param header : header to parse.

+     */

+    private void parseAbstractFactoryType(Bundle bundle, String header) {

+        String[] arr = ParseUtils.split(header, ",");

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

+            String[] arr2 = ParseUtils.split(arr[i], ":");

+            String type = arr2[0];

+            Class clazz;

+            try {

+                clazz = bundle.loadClass(arr2[1]);

+            } catch (ClassNotFoundException e) {

+                m_logger.log(Logger.ERROR, "Cannot load the extension " + type, e);

+                return;

+            }

+            ManagedAbstractFactoryType mft = new ManagedAbstractFactoryType(clazz, type, bundle);

+            m_factoryTypes.add(mft);

+            m_logger.log(Logger.WARNING, "New factory type available: " + type);

+

+            for (int j = m_unboundTypes.size() - 1; j >= 0; j--) {

+                UnboundComponentType unbound = (UnboundComponentType) m_unboundTypes.get(j);

+                if (unbound.m_type.equals(type)) {

+                    createAbstractFactory(unbound.m_bundle, unbound.m_description);

+                    m_unboundTypes.remove(unbound);

+                }

+            }

+        }

+    }

+

     /**

      * Parse the internal metadata (from the manifest (in the iPOJO-Components property)).

      * @param bundle : the owner bundle.

@@ -140,35 +227,40 @@
     private void parse(Bundle bundle, String components) throws IOException, ParseException {

         ManifestMetadataParser parser = new ManifestMetadataParser();

         parser.parseHeader(components);

-          

-        Element[] componentsMetadata = parser.getComponentsMetadata(); // Get the component type declaration

-        for (int i = 0; i < componentsMetadata.length; i++) { addComponentFactory(bundle, componentsMetadata[i]); }

-        

-        start(bundle, parser.getInstances());

+

+        Element[] metadata = parser.getComponentsMetadata(); // Get the component type declaration

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

+            createAbstractFactory(bundle, metadata[i]);

+        }

+

+        Dictionary[] instances = parser.getInstances();

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

+            m_creator.addInstance(instances[i], bundle.getBundleId());

+        }

     }

 

     /**

      * iPOJO Starting method.

-     * @param bc : iPOJO bundle context.

-     * @throws Exception : the start method failed.

+     * @param context : iPOJO bundle context.

      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)

      */

-    public void start(BundleContext bc) throws Exception {

-        m_context = bc;

-        m_bundleId = bc.getBundle().getBundleId();

-        m_components = new Hashtable();

-        m_creators = new Hashtable();

+    public void start(BundleContext context) {

+        m_context = context;

+        m_bundle = context.getBundle();

+        m_creator = new InstanceCreator(context);

+

+        m_logger = new Logger(m_context, "IPOJO Extender");

 

         // Begin by initializing core handlers

-        startManagementFor(bc.getBundle());

+        startManagementFor(m_bundle);

 

         synchronized (this) {

             // listen to any changes in bundles.

             m_context.addBundleListener(this);

             // compute already started bundles.

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

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

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

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

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

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

                 }

             }

         }

@@ -176,96 +268,238 @@
 

     /**

      * Stop the iPOJO Management.

-     * @param bc : bundle context.

-     * @throws Exception : the stop method failed.

+     * @param context : bundle context.

      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)

      */

-    public void stop(BundleContext bc) throws Exception {

+    public void stop(BundleContext context) {

         m_context.removeBundleListener(this);

-        Enumeration e = m_components.keys();

-        while (e.hasMoreElements()) {

-            ComponentFactory[] cfs = (ComponentFactory[]) m_components.get(e.nextElement());

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

-                cfs[i].stop();

+

+        for (int k = 0; k < m_factoryTypes.size(); k++) {

+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);

+

+            if (mft.m_created != null) {

+                Iterator iterator = mft.m_created.keySet().iterator();

+                while (iterator.hasNext()) {

+                    Bundle key = (Bundle) iterator.next();

+                    List list = (List) mft.m_created.get(key);

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

+                        IPojoFactory factory = (IPojoFactory) list.get(i);

+                        m_creator.removeFactory(factory);

+                        factory.dispose();

+                    }

+                }

             }

         }

-        m_components = null;

-        Enumeration e2 = m_creators.keys();

-        while (e2.hasMoreElements()) {

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

-            creator.stop();

-        }

-        m_creators = null;

+

+        m_factoryTypes = null;

+        m_creator = null;

     }

-    

+

     /**

      * Add a component factory to the factory list.

-     * @param cm : the new component metadata.

+     * @param metadata : the new component metadata.

      * @param bundle : the bundle.

      */

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

-        ComponentFactory factory = null;

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

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

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

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

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

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

-        } else {

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

-        }

-

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

-        

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

-        if (cfs != null && cfs.length != 0) {

-            ComponentFactory[] newFactory = new ComponentFactory[cfs.length + 1];

-            System.arraycopy(cfs, 0, newFactory, 0, cfs.length);

-            newFactory[cfs.length] = factory;

-            cfs = newFactory;

-            m_components.put(bundle, cfs);

-        } else {

-            m_components.put(bundle, new ComponentFactory[] {factory}); // Else create an array of size one with the new Factory 

-        }

-    }

-    

-    /**

-     * Start the management of factories and create instances.

-     * @param bundle : the bundle. 

-     * @param confs : the instances to create.

-     */

-    private void start(Bundle bundle, Dictionary[] confs) {

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

-        

-        // Start the factories

-        if (cfs != null) {

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

-                cfs[j].start();

+    private void createAbstractFactory(Bundle bundle, Element metadata) {

+        ManagedAbstractFactoryType factoryType = null;

+        // First, look for factory-type (component, handler, composite ...)

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

+            ManagedAbstractFactoryType type = (ManagedAbstractFactoryType) m_factoryTypes.get(i);

+            if (type.m_type.equals(metadata.getName())) {

+                factoryType = type;

+                break;

             }

         }

 

-        // Create the instance creator if needed.

-        if (confs.length > 0) {

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

+        // If not found, return. It will wait for a new component type factory.

+        if (factoryType == null) {

+            m_logger.log(Logger.WARNING, "Type of component not yet recognized : " + metadata.getName());

+            m_unboundTypes.add(new UnboundComponentType(metadata.getName(), metadata, bundle));

+            return;

+        }

+

+        // Once found, we invoke the AbstractFactory constructor to create the component factory. 

+        Class clazz = factoryType.m_clazz;

+        try {

+            // Look for the constructor, and invoke it.

+            Constructor cst = clazz.getConstructor(new Class[] { BundleContext.class, Element.class });

+            IPojoFactory factory = (IPojoFactory) cst.newInstance(new Object[] { getBundleContext(bundle), metadata });

+

+            // Add the created factory in the m_createdFactories map.

+            if (factoryType.m_created == null) {

+                factoryType.m_created = new HashMap();

+                List list = new ArrayList();

+                list.add(factory);

+                factoryType.m_created.put(bundle, list);

+            } else {

+                List list = (List) factoryType.m_created.get(bundle);

+                if (list == null) {

+                    list = new ArrayList();

+                    list.add(factory);

+                    factoryType.m_created.put(bundle, list);

+                } else {

+                    list.add(factory);

+                }

+            }

+

+            // Start the created factory.

+            factory.start();

+            // Then add the factory to the instance creator.

+            m_creator.addFactory(factory);

+

+        } catch (SecurityException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);

+        } catch (NoSuchMethodException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName() + ": the given class constructor cannot be found");

+        } catch (IllegalArgumentException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);

+        } catch (InstantiationException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);

+        } catch (IllegalAccessException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);

+        } catch (InvocationTargetException e) {

+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e.getTargetException());

         }

     }

-    

+

     /**

-     * Log an error message in a log service (if available) and display the message in the console.

-     * @param message : the message to log

-     * @param t : an attached error (can be null)

+     * Structure storing an iPOJO extension.

      */

-    private void err(String message, Throwable t) {

-        ServiceReference ref = m_context.getServiceReference(LogService.class.getName());

-        if (ref != null) {

-            LogService log = (LogService) m_context.getService(ref);

-            log.log(LogService.LOG_ERROR, message, t);

-            m_context.ungetService(ref);

-        }

-        if (t != null) {

-            System.err.println("[iPOJO-Core] " + message + " : " + t.getMessage());

-        } else {

-            System.err.println("[iPOJO-Core] " + message);

+    private final class ManagedAbstractFactoryType {

+        /**

+         * TYpe (i.e.) name of the extension.

+         */

+        String m_type;

+

+        /**

+         * Abstract Factory class.

+         */

+        Class m_clazz;

+

+        /**

+         * Bundle object containing the declaration of the extension.

+         */

+        Bundle m_bundle;

+

+        /**

+         * Factories created by this extension. 

+         */

+        private Map m_created;

+

+        /**

+         * Constructor.

+         * @param factory : abstract factory class.

+         * @param type : name of the extension.

+         * @param bundle : bundle declaring the extension.

+         */

+        protected ManagedAbstractFactoryType(Class factory, String type, Bundle bundle) {

+            m_bundle = bundle;

+            m_clazz = factory;

+            m_type = type;

         }

     }

+

+    /**

+     * Structure storing unbound component type declaration.

+     * Unbound means that there is no extension able to manage it.

+     */

+    private final class UnboundComponentType {

+        /**

+         * Component type description.

+         */

+        private final Element m_description;

+

+        /**

+         * Bundle declaring this type.

+         */

+        private final Bundle m_bundle;

+

+        /**

+         * Required extension name.

+         */

+        private final String m_type;

+

+        /**

+         * Constructor.

+         * @param description : description of the component type.

+         * @param bundle : bundle declaring this type.

+         * @param type : required extension name.

+         */

+        protected UnboundComponentType(String type, Element description, Bundle bundle) {

+            m_type = type;

+            m_description = description;

+            m_bundle = bundle;

+        }

+    }

+

+    /**

+     * Compute the bundle context from the bundle class by introspection.

+     * @param bundle : bundle.

+     * @return the bundle context object or null if not found.

+     */

+    public BundleContext getBundleContext(Bundle bundle) {

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

+

+        // getBundleContext (OSGi 4.1)

+        Method meth = null;

+        try {

+            meth = bundle.getClass().getMethod("getBundleContext", new Class[0]);

+        } catch (SecurityException e) {

+            // Nothing do to, will try the Equinox method

+        } catch (NoSuchMethodException e) {

+            // Nothing do to, will try the Equinox method

+        }

+

+        // try Equinox getContext if not found.

+        if (meth == null) {

+            try {

+                meth = bundle.getClass().getMethod("getContext", new Class[0]);

+            } catch (SecurityException e) {

+                // Nothing do to, will try field inspection

+            } catch (NoSuchMethodException e) {

+                // Nothing do to, will try field inspection

+            }

+        }

+

+        if (meth != null) {

+            if (! meth.isAccessible()) { 

+                // If not accessible, try to set the accessibility.

+                meth.setAccessible(true);

+            }

+            try {

+                return (BundleContext) meth.invoke(bundle, new Object[0]);

+            } catch (IllegalArgumentException e) {

+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);

+                return null;

+            } catch (IllegalAccessException e) {

+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);

+                return null;

+            } catch (InvocationTargetException e) {

+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e.getTargetException());

+                return null;

+            }

+        }

+

+        // Else : Field inspection (KF and Prosyst)        

+        Field[] fields = bundle.getClass().getDeclaredFields();

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

+            if (BundleContext.class.isAssignableFrom(fields[i].getType())) {

+                if (!fields[i].isAccessible()) {

+                    fields[i].setAccessible(true);

+                }

+                try {

+                    return (BundleContext) fields[i].get(bundle);

+                } catch (IllegalArgumentException e) {

+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);

+                    return null;

+                } catch (IllegalAccessException e) {

+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);

+                    return null;

+                }

+            }

+        }

+        m_logger.log(Logger.ERROR, "Cannot find the BundleContext for " + bundle.getSymbolicName(), null);

+        return null;

+    }

+

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
index bcc2d55..a8bff35 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Factory.java
@@ -21,7 +21,7 @@
 import java.util.Dictionary;
 import java.util.List;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.osgi.framework.BundleContext;
 
@@ -72,7 +72,7 @@
      * Get the component type description.
      * @return the component type description object
      */
-    ComponentDescription getComponentDescription();
+    ComponentTypeDescription getComponentDescription();
 
     /**
      * Check if the given configuration is acceptable as a configuration of a component instance.
@@ -97,15 +97,15 @@
 
     /**
      * Add a factory state listener on the current factory.
-     * @param l : the listener to add
+     * @param listener : the listener to add
      */
-    void addFactoryStateListener(FactoryStateListener l);
+    void addFactoryStateListener(FactoryStateListener listener);
 
     /**
      * Remove the given factory state listener from the listener list.
-     * @param l : the listener to remove
+     * @param listener : the listener to remove
      */
-    void removeFactoryStateListener(FactoryStateListener l);
+    void removeFactoryStateListener(FactoryStateListener listener);
 
     /**
      * Get the list of missing handlers.
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java
new file mode 100644
index 0000000..d8d4823
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java
@@ -0,0 +1,47 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+/**

+* Field interceptor.

+* A class implementing this interface is able to be notified of field accesses.

+* The listener need to be register on the instance manager. 

+* 

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

+*/

+public interface FieldInterceptor {

+    

+    /**

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

+     * @param pojo : the pojo object setting the value

+     * @param fieldName : the field name

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

+     */

+    void onSet(Object pojo, String fieldName, Object value);

+

+    /**

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

+     * @param pojo : the pojo object getting the value

+     * @param fieldName : the field name

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

+     * @return : the managed value of the field

+     */

+    Object onGet(Object pojo, String fieldName, Object value);

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
index 48cb786..42107af 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Handler.java
@@ -20,7 +20,7 @@
 
 import java.util.Dictionary;
 
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.util.Logger;
@@ -31,17 +31,17 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public abstract class Handler {
-    
+
     /**
      * Handler namespace property.
      */
     public static final String HANDLER_NAMESPACE_PROPERTY = "handler.namespace";
-    
+
     /**
      * Handler name property. 
      */
     public static final String HANDLER_NAME_PROPERTY = "handler.name";
-    
+
     /**
      * Handler type property. 
      */
@@ -51,39 +51,73 @@
      * Handler priority.
      */
     public static final String HANDLER_LEVEL_PROPERTY = "handler.level";
-    
+
     /**
-     * Handler logger.
+     * Handler validity.
      */
-    private Logger m_logger;
-    
+    protected boolean m_isValid = true;
+
     /**
-     * Set the logger use by this handler.
-     * @param logger : the logger object to use.
+     * HandlerManager managing the current handler.
      */
-    final void setLogger(Logger logger) {
-        m_logger = logger;
-    }
-    
+    protected HandlerManager m_instance;
+
     /**
-     * Log method.
-     * @param level : message level (Logger class constant)
+     * Set the factory attached to this handler object.
+     * This method must be override to depend on each component factory type. 
+     * @param factory : the factory.
+     */
+    public abstract void setFactory(Factory factory);
+
+    /**
+     * Get the logger to use in the handler.
+     * This method must be override to depend on each component factory type logging policy.
+     * @return the logger.
+     */
+    public abstract Logger getLogger();
+
+    /**
+     * Log method (warning).
      * @param message : message to log
      */
-    public final void log(int level, String message) {
-        m_logger.log(level, message);
+    public final void warn(String message) {
+        getLogger().log(Logger.WARNING, message);
     }
-    
+
     /**
-     * Log method.
-     * @param level : message level (Logger class constant)
+     * Log method (error).
      * @param message : message to log
-     * @param ex : exception to attach to the message
      */
-    public final void log(int level, String message, Throwable ex) {
-        m_logger.log(level, message, ex);
+    public final void error(String message) {
+        getLogger().log(Logger.ERROR, message);
     }
-    
+
+    /**
+     * Log method (info).
+     * @param message : message to log
+     */
+    public final void info(String message) {
+        getLogger().log(Logger.INFO, message);
+    }
+
+    /**
+     * Log method (warning).
+     * @param message : message to log
+     * @param exception : exception to attach to the message
+     */
+    public final void warn(String message, Throwable exception) {
+        getLogger().log(Logger.WARNING, message, exception);
+    }
+
+    /**
+     * Log method (error).
+     * @param message : message to log
+     * @param exception : exception to attach to the message
+     */
+    public final void error(String message, Throwable exception) {
+        getLogger().log(Logger.ERROR, message, exception);
+    }
+
     /**
      * Get a plugged handler of the same container.
      * This method must be call only in the start method (or after). 
@@ -93,41 +127,65 @@
      * @return the handler object or null if the handler is not found.
      */
     public abstract Handler getHandler(String name);
-    
+
     /**
      * Attach the current handler object to the given component instance.
      * An attached handler becomes a part of the instance container.
-     * @param ci : the component instance on which the current handler will be attached.
+     * @param instance : the component instance on which the current handler will be attached.
      */
-    protected abstract void attach(ComponentInstance ci);
-    
+    protected abstract void attach(ComponentInstance instance);
+
     /**
      * Check if the current handler is valid.
+     * This check test the handlers validity.
      * This method must not be override.
      * @return true if the handler is valid.
      */
     public final boolean isValid() {
         return ((Pojo) this).getComponentInstance().getState() == ComponentInstance.VALID;
     }
-    
-    
+
+    /**
+     * Set the validity of the current handler.
+     * @param isValid : if true the handler becomes valid, else it becomes invalid.
+     */
+    public final void setValidity(boolean isValid) {
+        if (m_isValid != isValid) {
+            m_isValid = isValid;
+            HandlerManager instance = getHandlerManager();
+            if (isValid) {
+                instance.stateChanged(instance, ComponentInstance.VALID);
+            } else {
+                instance.stateChanged(instance, ComponentInstance.INVALID);
+            }
+        }
+    }
+
+    public final boolean getValidity() {
+        return m_isValid;
+    }
+
     /**
      * Get the component instance of the current handler.
      * @return : the component instance.
      */
-    public final ComponentInstance getInstance() {
-        return ((Pojo) this).getComponentInstance();
+    public final HandlerManager getHandlerManager() {
+        if (m_instance != null) { return m_instance; }
+        m_instance = (HandlerManager) ((Pojo) this).getComponentInstance();
+        return m_instance;
     }
-    
+
     /**
      * Initialize component factory.
      * This method aims to gather component factory properties. Each handler wanting to contribute need to override this 
      * method and add properties to the given component description.
-     * @param cd : component description.
+     * @param typeDesc : component description.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : if the metadata are not correct (early detection).
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {  }
+    public void initializeComponentFactory(ComponentTypeDescription typeDesc, Element metadata) throws ConfigurationException {
+        // The default implementation does nothing.
+    }
 
     /**
      * Configure the handler.
@@ -151,7 +209,9 @@
      * This method is called when the component state changed.
      * @param state : the new state
      */
-    public void stateChanged(int state) { }
+    public void stateChanged(int state) {
+        // The default implementation does nothing.
+    }
 
     /**
      * Return the current handler description.
@@ -166,5 +226,7 @@
      * The instance is reconfiguring.
      * @param configuration : New instance configuration.
      */
-    public void reconfigure(Dictionary configuration) { }
+    public void reconfigure(Dictionary configuration) {
+        // The default implementation does nothing.
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
index 04bc706..08bff14 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
@@ -18,20 +18,12 @@
  */

 package org.apache.felix.ipojo;

 

-import java.util.ArrayList;

-import java.util.Collection;

 import java.util.Dictionary;

-import java.util.Iterator;

-import java.util.List;

 import java.util.Properties;

 

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

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

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

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

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

 import org.osgi.framework.BundleContext;

-import org.osgi.framework.InvalidSyntaxException;

-import org.osgi.framework.ServiceRegistration;

 

 /**

  * The component factory manages component instance objects. This management

@@ -43,20 +35,20 @@
 public class HandlerFactory extends ComponentFactory implements Factory {

 

     /**

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

+     * iPOJO Default Namespace.

      */

-    private ServiceRegistration m_sr;

-    

+    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";

+

     /**

      * Handler type (composite|primitive).

      * Default: handler.

      */

     private String m_type = "primitive";

-    

+

     /**

      * Default iPOJO Namespace.

      */

-    private String m_namespace = IPojoConfiguration.IPOJO_NAMESPACE;

+    private String m_namespace = IPOJO_NAMESPACE;

 

     /**

      * Get the handler start level.

@@ -67,114 +59,67 @@
 

     /**

      * Create a composite factory.

-     * @param bc : bundle context

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

+     * @param context : bundle context

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

+     * @throws ConfigurationException occurs when the element describing the factory is malformed.

      */

-    public HandlerFactory(BundleContext bc, Element cm) {

-        super(bc, cm);

-        

+    public HandlerFactory(BundleContext context, Element metadata) throws ConfigurationException {

+        super(context, metadata);

+

         // Get the name

-        m_factoryName = cm.getAttribute("name").toLowerCase();

-        if (m_factoryName == null) {

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

-            return;

-        }

-        

+        m_factoryName = metadata.getAttribute("name");

+        if (m_factoryName == null) { throw new ConfigurationException("An Handler needs a name"); }

+

         // Get the type

-        String t = cm.getAttribute("type");

-        if (t != null) {

-            m_type = t;

+        String type = metadata.getAttribute("type");

+        if (type != null) {

+            m_type = type;

         }

-        

-        String l = cm.getAttribute("level");

-        if (l != null) {

-            m_level = new Integer(l).intValue();

+

+        String level = metadata.getAttribute("level");

+        if (level != null) {

+            m_level = new Integer(level).intValue();

         }

-        

+

         // Get the namespace

-        String ns = cm.getAttribute("namespace");

-        if (ns != null) {

-            m_namespace = ns.toLowerCase();

-        }        

+        String namespace = metadata.getAttribute("namespace");

+        if (namespace != null) {

+            m_namespace = namespace.toLowerCase();

+        }

     }

-    

+

     public String getNamespace() {

         return m_namespace;

     }

-    

+

     public String getHandlerName() {

         return m_namespace + ":" + getName();

     }

-    

+

     public String getType() {

         return m_type;

     }

-    

+

     public int getStartLevel() {

         return m_level;

     }

 

-    /**

-     * Start all the instance managers.

-     */

-    public synchronized void start() {

-        if (m_sr != null) { // Already started.

-            return;

-        }

-        

-        if (m_handlerIdentifiers.size() != 0) {

-            try {

-                String filter = "(&(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" 

-                    + "(factory.state=1)"

-                    + ")";

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

-                m_tracker.open();

-            } catch (InvalidSyntaxException e) {

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

-                stop();

-                return;

-            }

-        }

-                

-        try {

-            computeFactoryState();

-        } catch (ConfigurationException e) {

-            m_logger.log(Logger.ERROR, "Cannot initilize the factory " + e.getMessage());

-            stop();

-            return;

-        }

-        

-        // Exposition of the factory service (always public for handlers)

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

+    public ComponentTypeDescription getComponentTypeDescription() {

+        return new HandlerTypeDescription(this);

     }

-    

+

     /**

      * Stop the factory.

      * This method does not disposed created instances.

      * These instances will be disposed by the instance managers.

      */

-    public synchronized void stop() {

-        if (m_sr != null) {

-            m_sr.unregister();

-            m_sr = null;

-        }

-        

+    public synchronized void stopping() {

         if (m_tracker != null) {

             m_tracker.close();

             m_tracker = null;

         }

-        

-        // Release each handler

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

-            ((HandlerIdentifier) m_handlerIdentifiers.get(i)).unRef();

-        }

-        

-        m_handlerIdentifiers.clear();        

-        m_listeners.clear();

-        m_state = INVALID;        

     }

-    

-    

+

     /**

      * Compute factory service properties.

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

@@ -183,164 +128,53 @@
      */

     protected Properties getProperties() {

         Properties props = new Properties();

-        

-        // Add factory state

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

 

-        props.put(Handler.HANDLER_NAME_PROPERTY, m_factoryName);

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

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

-        if (m_level != Integer.MAX_VALUE) {

-            props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));

-        }

-        

         return props;

     }

-    

-    /**

-     * Compute handler factory state.

-     * @throws ConfigurationException : occurs when an handler cannot be initialized.

-     */

-    protected void computeFactoryState() throws ConfigurationException {

-        boolean isValid = true;

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

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

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

-        }

-        

-        if (isValid) {            

-            if (m_state == INVALID) {

-                m_state = VALID;

-                

-                if (m_sr == null) {

-                    m_componentDesc = new ComponentDescription(this);

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

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

-                        HandlerManager hm = getHandlerInstance(hi, null);

-                        hm.getHandler();

-                        Handler ch = hm.getHandler();

-                        ch.setLogger(getLogger());

-                        ch.initializeComponentFactory(m_componentDesc, m_componentMetadata);

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

-                    }

-                }

-                

-                if (m_sr != null) {

-                    m_sr.setProperties(getProperties());

-                }

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

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

-                }

-                return;

-            }

-        } else {

-            if (m_state == VALID) {

-                m_state = INVALID;

-                

-                // Notify listeners.

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

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

-                }

 

-                // Dispose created instances.

-                final Collection col = m_componentInstances.values();

-                final Iterator it = col.iterator();

-                while (it.hasNext()) {

-                    InstanceManager ci = (InstanceManager) it.next();

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

-                        ci.kill();

-                    }

-                    m_instancesName.remove(ci.m_name);

-                }

-

-                m_componentInstances.clear();

-

-                if (m_sr != null) {

-                    m_sr.setProperties(getProperties());

-                }

-                

-                return;

-            }

-        }

-    }

-    

     /**

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

      * property.

      * @param configuration : configuration of the created instance.

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

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

+     * @param handlers : handler array to used.

      * @return the created component instance.

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

      * not consistent with the component type of this factory.

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

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

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

      */

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

-        if (m_state == Factory.INVALID) {

-            throw new MissingHandlerException(getMissingHandlers());

-        }

-        

-        if (configuration == null) {

-            configuration = new Properties();

-        }

-        

-        String in = null;

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

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

-        } else {

-            in = generateName();

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

-        }

-        

-        if (m_instancesName.contains(in)) {

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

-        } else {

-            m_instancesName.add(in);

-        }

-

-        BundleContext context = null;

-        if (serviceContext == null) {

-            context = new IPojoContext(m_context);

-        } else {

-            context = new IPojoContext(m_context, serviceContext);

-        }

-        List handlers = new ArrayList();

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

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

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

-        }

-        

-        HandlerManager instance = new HandlerManager(this, context, (HandlerManager[]) handlers.toArray(new HandlerManager[handlers.size()]));

+    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {

+        HandlerManager instance = new HandlerManager(this, context, handlers);

         instance.configure(m_componentMetadata, configuration);

-

-        m_componentInstances.put(in, instance);

-        

-        

         return instance;

     }

-    

-    /**

-     * Return an handler object.

-     * @param hi : handler to create.

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

-     * @return the Handler object.

-     */

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

-        try {

-            return (HandlerManager) hi.getFactory().createComponentInstance(null, sc);

-        } catch (MissingHandlerException e) {

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

-            stop();

-            return null;

-        } catch (UnacceptableConfiguration e) {

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

-            stop();

-            return null;

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

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

-            stop();

-            return null;

+

+    private class HandlerTypeDescription extends ComponentTypeDescription {

+

+        /**

+         * Constructor.

+         * @param factory : factory.

+         */

+        public HandlerTypeDescription(Factory factory) {

+            super(factory);

+        }

+

+        /**

+         * Add properties to publish : 

+         * handler.name, handler.namespace, handler.type and handler.level if the level is not Integer.MAX.

+         * @return return the dictionary to publish.

+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()

+         */

+        public Dictionary getPropertiesToPublish() {

+            Dictionary props = super.getPropertiesToPublish();

+

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

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

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

+            if (m_level != Integer.MAX_VALUE) {

+                props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));

+            }

+            return props;

         }

     }

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
index 7754ef5..e2f4003 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
@@ -24,12 +24,12 @@
 import org.osgi.framework.BundleContext;

 

 /**

-* The handler manager manages an handler instance.

-* 

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

-*/

+ * The handler manager manages an handler instance.

+ * 

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

+ */

 public class HandlerManager extends InstanceManager {

-    

+

     /**

      * Handler object (contained).

      */

@@ -38,13 +38,13 @@
     /**

      * Constructor.

      * @param factory : handler factory

-     * @param bc : bundle context

+     * @param context : bundle context

      * @param handlers : handler array

      */

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

-        super(factory, bc, handlers);

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

+        super(factory, context, handlers);

     }

-    

+

     /**

      * Get the contained handler object.

      * If not already created it creates the object.

@@ -56,73 +56,68 @@
         }

         return m_handler;

     }

-    

+

     /**

      * Create and initialize the handler object.

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

-     * @param cm : component metadata.

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

+     * @param metadata : component metadata.

      * @param configuration : instance configuration.

      * @throws ConfigurationException if the handler configuration failed.

      */

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

+    public void init(ComponentInstance instance, Element metadata, Dictionary configuration) throws ConfigurationException {

         createHandlerObject();

-        m_handler.attach(ci);

-        m_handler.configure(cm, configuration);

+        m_handler.setFactory(instance.getFactory());

+        m_handler.attach(instance);

+        m_handler.configure(metadata, configuration);

     }

-    

+

     /**

      * Create the handler object.

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

      */

     private void createHandlerObject() {

         if (m_handler != null) { return; }

-        Handler h  = (Handler) createPojoObject();

-        if (h instanceof PrimitiveHandler) {

-            m_handler = (PrimitiveHandler) h;

-        } else {

-            m_handler = (CompositeHandler) h;

-        }

+        m_handler = (Handler) createPojoObject();

     }

-    

+

     /**

      * Start the instance manager.

      */

     public synchronized void start() {

-        if (m_state != STOPPED) {

-            return;

-        } // Instance already started

+        if (m_state != STOPPED) { return; } // Instance already started

 

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

             m_handlers[i].addInstanceStateListener(this);

             m_handlers[i].start();

         }

-        

+

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

-        

+

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

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

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

                 setState(INVALID);

                 return;

             }

         }

-        setState(VALID);

+        if (m_handler.getValidity()) {

+            setState(VALID);

+        } else {

+            setState(INVALID);

+        }

     }

-    

+

     /**

      * Stop the instance manager.

      */

     public synchronized void stop() {

-        if (m_state == STOPPED) {

-            return;

-        } // Instance already stopped

-        

+        if (m_state == STOPPED) { return; } // Instance already stopped

 

         setState(INVALID);

-        

+

         if (m_handler != null) {

             m_handler.stop();

         }

-        

+

         // Stop all the handlers

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

             m_handlers[i].removeInstanceStateListener(this);

@@ -130,13 +125,13 @@
         }

 

         m_state = STOPPED;

-        if (m_instanceListeners != null) {

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

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

+        if (m_listeners != null) {

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

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

             }

         }

     }

-    

+

     /** 

      * Dispose the instance.

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

@@ -145,7 +140,7 @@
         super.dispose();

         m_handler = null;

     }

-    

+

     /**

      * Kill the current instance.

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

@@ -155,4 +150,31 @@
         m_handler = null;

     }

 

+    /**

+     * State Change listener callback.

+     * This method is notified at each time a plugged handler becomes invalid.

+     * @param instance : changing instance 

+     * @param newState : new state

+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)

+     */

+    public synchronized void stateChanged(ComponentInstance instance, int newState) {

+        if (m_state <= STOPPED) { return; }

+

+        // Update the component state if necessary

+        if (newState == INVALID && m_state == VALID) {

+            // Need to update the state to UNRESOLVED

+            setState(INVALID);

+            return;

+        }

+        if (newState == VALID && m_state == INVALID) {

+            // An handler becomes valid => check if all handlers are valid

+            if (!m_handler.getValidity()) { return; }

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

+                if (m_handlers[i].getState() != VALID) { return; }

+            }

+            setState(VALID);

+            return;

+        }

+    }

+

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
deleted file mode 100644
index 78d3434..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoConfiguration.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo;
-
-import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.composite.service.importer.ImportHandler;
-import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
-import org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler;
-import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
-import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
-import org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler;
-import org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * iPOJO Configuration : Default Log Level - Available (core) handlers.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class IPojoConfiguration {
-
-    /**
-     * iPOJO logger log level.
-     */
-    public static final int LOG_LEVEL = Logger.WARNING;
-    
-    
-    /**
-     * iPOJO Default Namespace.
-     */
-    public static final String IPOJO_NAMESPACE = "org.apache.felix.ipojo";
-
-    /**
-     * Available handlers in the iPOJO bundle.
-     */
-    public static final Class[] INTERNAL_HANDLERS = new Class[] { 
-        DependencyHandler.class, 
-        ProvidedServiceHandler.class, 
-        ConfigurationHandler.class,
-        LifecycleCallbackHandler.class,
-        ControllerHandler.class,
-        ArchitectureHandler.class
-    };
-
-    /**
-     * Available composite handlers in the iPOJO bundle.
-     */
-    public static final Class[] INTERNAL_COMPOSITE_HANDLERS = new Class[] { 
-        ServiceInstantiatorHandler.class, 
-        ImportHandler.class,
-        InstanceHandler.class,
-        org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler.class,
-        org.apache.felix.ipojo.composite.architecture.ArchitectureHandler.class
-    };
-    
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
index a1e2e53..09bfcdf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -54,25 +54,24 @@
     /**
      * Constructor. Used when the service context = the bundle context
      * 
-     * @param bc : bundle context
+     * @param context : bundle context
      */
-    public IPojoContext(BundleContext bc) {
-        m_bundleContext = bc;
+    public IPojoContext(BundleContext context) {
+        m_bundleContext = context;
     }
 
     /**
      * Constructor. Used when the service context and the bundle context are
      * different
      * 
-     * @param bc : bundle context
-     * @param sc : service context
+     * @param bundleContext : bundle context
+     * @param serviceContext : service context
      */
-    public IPojoContext(BundleContext bc, ServiceContext sc) {
-        m_bundleContext = bc;
-        m_serviceContext = sc;
+    public IPojoContext(BundleContext bundleContext, ServiceContext serviceContext) {
+        m_bundleContext = bundleContext;
+        m_serviceContext = serviceContext;
     }
 
-   
     /**
      * Add a bundle listener.
      * @param listener : the listener to add
@@ -119,7 +118,6 @@
         }
     }
 
-
     /**
      * Create a Filter object.
      * @param filter : the string form of the LDAP filter to create
@@ -158,12 +156,12 @@
 
     /**
      * Get the bundle object with the given id.
-     * @param id : bundle id
+     * @param bundleId : bundle id
      * @return the bundle object
      * @see org.osgi.framework.BundleContext#getBundle(long)
      */
-    public Bundle getBundle(long id) {
-        return m_bundleContext.getBundle(id);
+    public Bundle getBundle(long bundleId) {
+        return m_bundleContext.getBundle(bundleId);
     }
 
     /**
@@ -175,7 +173,6 @@
         return m_bundleContext.getBundles();
     }
 
-
     /**
      * Get a data file.
      * @param filename : File name.
@@ -340,7 +337,7 @@
             return m_serviceContext.ungetService(reference);
         }
     }
-    
+
     /**
      * Get the global context, i.e. the bundle context of the factory.
      * @return the global bundle context.
@@ -348,15 +345,12 @@
     public BundleContext getGlobalContext() {
         return m_bundleContext;
     }
-    
+
     /**
      * Get the service context, i.e. the composite context.
      * @return the service context.
      */
     public ServiceContext getServiceContext() {
-        if (m_serviceContext == null) {
-            return this;
-        }
         return m_serviceContext;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
new file mode 100644
index 0000000..44ae438
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -0,0 +1,829 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.Properties;

+import java.util.Set;

+

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

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

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+/**

+ * This class abstracts iPOJO factories.

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

+ */

+public abstract class IPojoFactory implements Factory, ManagedServiceFactory {

+

+    /**

+     * List of the managed instance name. This list is shared by all factories.

+     */

+    protected static List m_instancesName = new ArrayList();

+

+    /**

+     * Component-Type description exposed by the factory service.

+     */

+    protected ComponentTypeDescription m_componentDesc;

+

+    /**

+     * List of the managed instance managers. The key of this map is the name (i.e. instance names) of the created instance

+     */

+    protected Map m_componentInstances = new HashMap();

+

+    /**

+     * Component Type provided by this factory.

+     */

+    protected Element m_componentMetadata;

+

+    /**

+     * The bundle context reference.

+     */

+    protected BundleContext m_context = null;

+

+    /**

+     * Factory Name. Could be the component class name if the factory name is not set.

+     */

+    protected String m_factoryName;

+

+    /**

+     * List of required handler.

+     */

+    protected List m_requiredHandlers = new ArrayList();

+

+    /**

+     * List of listeners.

+     */

+    protected List m_listeners = new ArrayList(2);

+

+    /**

+     * Logger for the factory (and all component instance).

+     */

+    protected Logger m_logger;

+

+    /**

+     * Is the factory public (expose as a service).

+     */

+    protected boolean m_isPublic;

+

+    /**

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

+     */

+    protected ServiceRegistration m_sr;

+

+    /**

+     * Factory state.

+     */

+    protected int m_state = Factory.INVALID;

+

+    /**

+     * Index used to generate instance name if not set.

+     */

+    private long m_index = 0;

+

+    /**

+     * Flag indicating if this factory has already a computed description or not.

+     */

+    private boolean m_described;

+

+    /**

+     * Constructor.

+     * @param context : bundle context of the bundle containing the factory.

+     * @param metadata : description of the component type.

+     * @throws ConfigurationException occurs when the element describing the factory is malformed.

+     */

+    public IPojoFactory(BundleContext context, Element metadata) throws ConfigurationException {

+        m_context = context;

+        m_componentMetadata = metadata;

+        m_factoryName = getFactoryName();

+        String fac = metadata.getAttribute("factory");

+        m_isPublic = fac == null || !fac.equalsIgnoreCase("false");

+        m_logger = new Logger(m_context, m_factoryName);

+        m_requiredHandlers = getRequiredHandlerList();

+    }

+

+    public ComponentTypeDescription getComponentTypeDescription() {

+        return new ComponentTypeDescription(this);

+    }

+

+    /**

+     * Add a factory listener.

+     * @param listener : the factory listener to add.

+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)

+     */

+    public void addFactoryStateListener(FactoryStateListener listener) {

+        synchronized (m_listeners) {

+            m_listeners.add(listener);

+        }

+    }

+

+    /**

+     * Get the logger used by instances of he current factory.

+     * @return the factory logger.

+     */

+    public Logger getLogger() {

+        return m_logger;

+    }

+

+    /**

+     * Compute the factory name.

+     * @return the factory name.

+     */

+    public abstract String getFactoryName();

+

+    /**

+     * Compute the required handler list.

+     * @return the required handler list

+     */

+    public abstract List getRequiredHandlerList();

+

+    /**

+     * Create an instance.

+     * @param config : instance configuration

+     * @param context : ipojo context to use

+     * @param handlers : handler array to use

+     * @return the new component instance.

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

+     */

+    public abstract ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers)

+            throws ConfigurationException;

+

+    /**

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

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

+     * @return the created component instance.

+     * @throws UnacceptableConfiguration : occurs if the given configuration is not consistent with the component type of this factory.

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

+     * @throws org.apache.felix.ipojo.ConfigurationException : occurs when the instance or type configuration are not correct.

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

+     */

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

+            ConfigurationException {

+        return createComponentInstance(configuration, null);

+    }

+

+    /**

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

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

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

+     * @return the created component instance.

+     * @throws UnacceptableConfiguration : occurs if the given configuration is not consistent with the component type of this factory.

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

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

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

+     */

+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, // NOPMD

+            MissingHandlerException, ConfigurationException {

+        if (configuration == null) {

+            configuration = new Properties();

+        }

+

+        try {

+            checkAcceptability(configuration);

+        } catch (UnacceptableConfiguration e) {

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

+            throw new UnacceptableConfiguration("The configuration "

+                    + configuration

+                    + " is not acceptable for "

+                    + m_factoryName

+                    + ": "

+                    + e.getMessage());

+        }

+

+        String name = null;

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

+            name = generateName();

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

+        } else {

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

+            if (m_instancesName.contains(name)) {

+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : Name already used");

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

+            }

+        }

+

+        IPojoContext context = null;

+        if (serviceContext == null) {

+            context = new IPojoContext(m_context);

+        } else {

+            context = new IPojoContext(m_context, serviceContext);

+        }

+

+        HandlerManager[] handlers = new HandlerManager[m_requiredHandlers.size()];

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

+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+            handlers[i] = getHandler(req, serviceContext);

+        }

+        try {

+            ComponentInstance instance = createInstance(configuration, context, handlers);

+            m_instancesName.add(name);

+            m_componentInstances.put(name, instance);

+            return instance;

+        } catch (ConfigurationException e) {

+            m_logger.log(Logger.ERROR, e.getMessage());

+            throw new ConfigurationException(e.getMessage(), m_factoryName);

+        }

+    }

+

+    public BundleContext getBundleContext() {

+        return m_context;

+    }

+

+    /**

+     * Get the factory class name.

+     * @return the factory classname.

+     * @see org.apache.felix.ipojo.Factory#getClassName()

+     */

+    public abstract String getClassName();

+

+    /**

+     * Get the component type description.

+     * @return the component type description object. Null if not already computed.

+     */

+    public ComponentTypeDescription getComponentDescription() {

+        return m_componentDesc;

+    }

+

+    /**

+     * Get the component type description (Element-Attribute form).

+     * @return the component type description.

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

+     */

+    public Element getDescription() {

+        if (m_componentDesc == null) {

+            return new Element("No description available for " + m_factoryName, "");

+        }

+        return m_componentDesc.getDescription();

+    }

+

+    /**

+     * Compute the list of missing handlers.

+     * @return list of missing handlers.

+     * @see org.apache.felix.ipojo.Factory#getMissingHandlers()

+     */

+    public List getMissingHandlers() {

+        List list = new ArrayList();

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

+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+            if (req.getReference() == null) {

+                list.add(req.getFullName());

+            }

+        }

+        return list;

+    }

+

+    public String getName() {

+        return m_factoryName;

+    }

+

+    /**

+     * Get the list of required handlers.

+     * @return list of required handlers.

+     * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()

+     */

+    public List getRequiredHandlers() {

+        List list = new ArrayList();

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

+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+            list.add(req.getFullName());

+        }

+        return list;

+    }

+

+    public int getState() {

+        return m_state;

+    }

+

+    /**

+     * Check if the configuration is acceptable.

+     * @param conf : the configuration to test.

+     * @return true if the configuration is acceptable.

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

+     */

+    public boolean isAcceptable(Dictionary conf) {

+        try {

+            checkAcceptability(conf);

+        } catch (MissingHandlerException e) {

+            return false;

+        } catch (UnacceptableConfiguration e) {

+            return false;

+        }

+        return true;

+    }

+

+    /**

+     * Check if the configuration is acceptable.

+     * @param conf : the configuration to test.

+     * @throws UnacceptableConfiguration occurs if the configuration is unacceptable.

+     * @throws MissingHandlerException occurs if an handler is missing.

+     */

+    public void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {

+        if (m_state == Factory.INVALID) {

+            throw new MissingHandlerException(getMissingHandlers());

+        }

+

+        // Check that the configuration does not override immutable properties.

+        PropertyDescription[] props = m_componentDesc.getProperties();

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

+            // Is the property immutable

+            if (props[i].isImmutable() && conf.get(props[i].getName()) != null) {

+                throw new UnacceptableConfiguration("The property " + props[i] + " cannot be overide : immutable property"); // The instance

+                // configuration try

+                // to override an

+                // immutable property.

+            }

+            // Is the property required.

+            if (props[i].getValue() == null && conf.get(props[i].getName()) == null) {

+                throw new UnacceptableConfiguration("The property " + props[i].getName() + " is missing"); // The property must be set.

+            }

+        }

+    }

+

+    /**

+     * Reconfigure an existing instance.

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

+     * @throws UnacceptableConfiguration : occurs if the new configuration is not consistent with the component type.

+     * @throws MissingHandlerException : occurs if the current factory is not valid.

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

+     */

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

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

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

+        }

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

+        ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);

+

+        if (instance == null) {

+            return; // The instance does not exist.

+        } else {

+            checkAcceptability(properties); // Test if the configuration is acceptable

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

+        }

+    }

+

+    /**

+     * Remove a factory listener.

+     * @param listener : the factory listener to remove.

+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)

+     */

+    public void removeFactoryStateListener(FactoryStateListener listener) {

+        synchronized (m_listeners) {

+            m_listeners.remove(listener);

+        }

+    }

+

+    /**

+     * Stopping method. This method is call when the factory is stopping.

+     */

+    public abstract void stopping();

+

+    /**

+     * Stop all the instance managers.

+     */

+    public synchronized void stop() {

+        if (m_sr != null) {

+            m_sr.unregister();

+            m_sr = null;

+        }

+

+        stopping();

+

+        if (m_state == VALID) {

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

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

+            }

+        }

+        m_state = INVALID;

+

+        // Dispose created instances.

+        Set col = m_componentInstances.keySet();

+        String[] keys = (String[]) col.toArray(new String[col.size()]);

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

+            ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);

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

+                instance.dispose();

+            }

+        }

+

+        // Release each handler

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

+            ((RequiredHandler) m_requiredHandlers.get(i)).unRef();

+        }

+

+        m_described = false;

+        m_componentDesc = null;

+        m_componentInstances.clear();

+    }

+

+    /**

+     * Destroy the factory. The factory cannot be restarted.

+     * Only the extender can call this method.

+     */

+    void dispose() {

+        stop();

+        m_componentMetadata = null;

+        m_componentInstances = null;

+        m_context = null;

+        m_requiredHandlers = null;

+        m_listeners = null;

+        m_logger = null;

+    }

+

+    /**

+     * Starting method. This method is called when the factory is starting.

+     */

+    public abstract void starting();

+

+    /**

+     * Start the factory.

+     */

+    public synchronized void start() {

+        if (m_described) { // Already started.

+            return;

+        }

+

+        m_componentDesc = getComponentTypeDescription();

+

+        starting();

+

+        computeFactoryState();

+

+        if (m_isPublic) {

+            // Exposition of the factory service

+            m_sr =

+                    m_context.registerService(new String[] { Factory.class.getName(), ManagedServiceFactory.class.getName() }, this, m_componentDesc

+                            .getPropertiesToPublish());

+        }

+    }

+

+    /**

+     * Create of update an instance.

+     * @param name : name of the instance

+     * @param properties : configuration of the instance

+     * @throws org.osgi.service.cm.ConfigurationException : if the configuration is not consistent for this component type

+     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)

+     */

+    public synchronized void updated(String name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {

+        InstanceManager instance = (InstanceManager) m_componentInstances.get(name);

+        if (instance == null) {

+            try {

+                properties.put("name", name); // Add the name in the configuration

+                createComponentInstance(properties);

+            } catch (UnacceptableConfiguration e) {

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

+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());

+            } catch (MissingHandlerException e) {

+                m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());

+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());

+            } catch (ConfigurationException e) {

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

+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());

+            }

+        } else {

+            try {

+                properties.put("name", name); // Add the name in the configuration

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

+            } catch (UnacceptableConfiguration e) {

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

+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());

+            } catch (MissingHandlerException e) {

+                m_logger.log(Logger.ERROR, "The facotry is not valid, at least one handler is missing : " + e.getMessage());

+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());

+            }

+        }

+    }

+

+    /**

+     * Delete an instance.

+     * @param name : name of the instance to delete

+     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)

+     */

+    public synchronized void deleted(String name) {

+        m_instancesName.remove(name);

+        ComponentInstance instance = (ComponentInstance) m_componentInstances.remove(name);

+        if (instance != null) {

+            instance.dispose();

+        }

+    }

+

+    /**

+     * Callback called by instance when disposed.

+     * @param instance : the destroyed instance

+     */

+    public void disposed(ComponentInstance instance) {

+        String name = instance.getInstanceName();

+        m_instancesName.remove(name);

+        m_componentInstances.remove(name);

+    }

+

+    /**

+     * Compute the component type description. The factory must be valid when calling this method.

+     */

+    protected void computeDescription() {

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

+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+            Handler handler = getHandler(req, null).getHandler();

+            try {

+                handler.setFactory(this);

+                handler.initializeComponentFactory(m_componentDesc, m_componentMetadata);

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

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

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

+                m_logger.log(Logger.ERROR, e.getMessage());

+                stop();

+                throw new IllegalStateException(e.getMessage());

+            }

+        }

+    }

+

+    /**

+     * Compute factory state.

+     */

+    protected void computeFactoryState() {

+        boolean isValid = true;

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

+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+            if (req.getReference() == null) {

+                isValid = false;

+                break;

+            }

+

+        }

+

+        if (isValid) {

+            if (m_state == INVALID) {

+

+                if (!m_described) {

+                    computeDescription();

+                    m_described = true;

+                }

+

+                m_state = VALID;

+                if (m_sr != null) {

+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());

+                }

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

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

+                }

+                return;

+            }

+        } else {

+            if (m_state == VALID) {

+                m_state = INVALID;

+

+                // Notify listeners.

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

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

+                }

+

+                // Dispose created instances.

+                Set col = m_componentInstances.keySet();

+                String[] keys = (String[]) col.toArray(new String[col.size()]);

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

+                    ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);

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

+                        instance.dispose();

+                    }

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

+                }

+

+                m_componentInstances.clear();

+

+                if (m_sr != null) {

+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());

+                }

+

+                return;

+            }

+        }

+    }

+

+    /**

+     * Check if the given handler identifier and the service reference can match.

+     * @param req : the handler identifier.

+     * @param ref : the service reference.

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

+     */

+    protected boolean match(RequiredHandler req, ServiceReference ref) {

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

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

+        if (HandlerFactory.IPOJO_NAMESPACE.equals(namespace)) {

+            return name.equals(req.getName()) && req.getNamespace() == null;

+        }

+        return name.equals(req.getName()) && namespace.equals(req.getNamespace());

+    }

+

+    /**

+     * Return the handler object for the given required handler. The handler is instantiated in the given service context.

+     * @param req : handler to create.

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

+     * @return the Handler object.

+     */

+    protected HandlerManager getHandler(RequiredHandler req, ServiceContext context) {

+        try {

+            return (HandlerManager) req.getFactory().createComponentInstance(null, context);

+        } catch (MissingHandlerException e) {

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

+            stop();

+            return null;

+        } catch (UnacceptableConfiguration e) {

+            m_logger.log(Logger.ERROR, "The creation of the handler "

+                    + req.getFullName()

+                    + " has failed (UnacceptableConfiguration): "

+                    + e.getMessage());

+            stop();

+            return null;

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

+            m_logger.log(Logger.ERROR, "The configuration of the handler "

+                    + req.getFullName()

+                    + " has failed (ConfigurationException): "

+                    + e.getMessage());

+            stop();

+            return null;

+        }

+    }

+

+    /**

+     * Helping method generating a new unique name.

+     * @return an non already used name

+     */

+    protected synchronized String generateName() {

+        String name = m_factoryName + "-" + m_index;

+        while (m_instancesName.contains(name)) {

+            m_index = m_index + 1;

+            name = m_factoryName + "-" + m_index;

+        }

+        return name;

+    }

+

+    /**

+     * Structure storing required handlers.

+     */

+    protected class RequiredHandler implements Comparable {

+        /**

+         * Factory to create this handler.

+         */

+        private HandlerFactory m_factory;

+

+        /**

+         * Handler name.

+         */

+        private String m_name;

+

+        /**

+         * Handler start level.

+         */

+        private int m_level = Integer.MAX_VALUE;

+

+        /**

+         * Handler namespace.

+         */

+        private String m_namespace;

+

+        /**

+         * Service Reference of the handler factory.

+         */

+        private ServiceReference m_reference;

+

+        /**

+         * Constructor.

+         * @param name : handler name.

+         * @param namespace : handler namespace.

+         */

+        public RequiredHandler(String name, String namespace) {

+            m_name = name;

+            m_namespace = namespace;

+        }

+

+        /**

+         * Equals method. Two handlers are equals if they have same name and namespace or they share the same service reference.

+         * @param object : object to compare to the current object.

+         * @return : true if the two compared object are equals

+         * @see java.lang.Object#equals(java.lang.Object)

+         */

+        public boolean equals(Object object) {

+            if (object instanceof RequiredHandler) {

+                RequiredHandler req = (RequiredHandler) object;

+                if (m_namespace == null) {

+                    return req.m_name.equalsIgnoreCase(m_name) && req.m_namespace == null;

+                } else {

+                    return req.m_name.equalsIgnoreCase(m_name) && m_namespace.equalsIgnoreCase(req.m_namespace);

+                }

+            } else {

+                return false;

+            }

+

+        }

+

+        /**

+         * Get the factory object used for this handler. The object is get when used for the first time.

+         * @return the factory object.

+         */

+        public HandlerFactory getFactory() {

+            if (m_reference == null) {

+                return null;

+            }

+            if (m_factory == null) {

+                m_factory = (HandlerFactory) m_context.getService(getReference());

+            }

+            return m_factory;

+        }

+

+        /**

+         * Get the handler full name (namespace:name).

+         * @return the handler full name

+         */

+        public String getFullName() {

+            if (m_namespace == null) {

+                return HandlerFactory.IPOJO_NAMESPACE + ":" + m_name;

+            } else {

+                return m_namespace + ":" + m_name;

+            }

+        }

+

+        public String getName() {

+            return m_name;

+        }

+

+        public String getNamespace() {

+            return m_namespace;

+        }

+

+        public ServiceReference getReference() {

+            return m_reference;

+        }

+

+        public int getLevel() {

+            return m_level;

+        }

+

+        /**

+         * Release the reference of the used factory.

+         */

+        public void unRef() {

+            if (m_reference != null) {

+                // m_context.ungetService(m_reference); // Will be unget automatically

+                m_factory = null;

+                m_reference = null;

+            }

+        }

+

+        /**

+         * Set the service reference. If the new service reference is null, it unget the used factory (if already get).

+         * @param ref : new service reference.

+         */

+        public void setReference(ServiceReference ref) {

+            m_reference = ref;

+            Integer level = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);

+            if (level != null) {

+                m_level = level.intValue();

+            }

+        }

+

+        /**

+         * Start level Comparison. This method is used to sort the handler array.

+         * @param object : object on which compare.

+         * @return -1, 0, +1 according to the comparison of their start level.

+         * @see java.lang.Comparable#compareTo(java.lang.Object)

+         */

+        public int compareTo(Object object) {

+            if (object instanceof RequiredHandler) {

+                RequiredHandler req = (RequiredHandler) object;

+                if (this.m_level == req.m_level) {

+                    return 0;

+                } else if (this.m_level < req.m_level) {

+                    return -1;

+                } else {

+                    return +1;

+                }

+            }

+            return 0;

+        }

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
index c356b2a..7333161 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
@@ -18,51 +18,238 @@
  */
 package org.apache.felix.ipojo;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.felix.ipojo.util.Logger;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
 
 /**
- * An instance creator aims to create instances and to track their factories.
- * It's allow to create instance from outside factories.
- * 
+ * An instance creator aims to create instances and to track their factories. It's allow to create instance from outside factories.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class InstanceCreator implements TrackerCustomizer, FactoryStateListener {
-    /**
-     * Bundle Context.
-     */
-    private BundleContext m_context;
+public class InstanceCreator implements FactoryStateListener {
 
     /**
      * Logger to log messages if error occurs.
      */
     private Logger m_logger;
-    
-    /**
-     * Private factories.
-     */
-    private ComponentFactory[] m_factories;
 
     /**
-     * This structure aims to manage a configuration. It stores all necessary
-     * information to create an instance and to track the factory.
+     * Configurations to create and maintains.
      */
-    private class ManagedConfiguration {
+    private List m_idle = new ArrayList();
+
+    /**
+     * Map storing created instance. [AbstractFactory, List [ManagedInstance]]
+     */
+    private Map m_attached = new HashMap();
+
+    /**
+     * Abstract Factory list.
+     */
+    private List m_factories = new ArrayList();
+
+    /**
+     * Constructor.
+     * @param context : iPOJO bundle context.
+     */
+    public InstanceCreator(BundleContext context) {
+        m_logger = new Logger(context, "iPOJO Instance Creator");
+    }
+
+    /**
+     * Add an instance to manage.
+     * @param instance : instance configuration
+     * @param bundle : bundle id declaring the instance
+     */
+    synchronized void addInstance(Dictionary instance, long bundle) {
+        ManagedInstance managed = new ManagedInstance(instance, bundle);
+        for (int i = 0; i < m_factories.size(); i++) {
+            IPojoFactory factory = (IPojoFactory) m_factories.get(i);
+            if (factory.getState() == Factory.VALID && managed.match(factory)) {
+                managed.create(factory);
+                List list = (List) m_attached.get(factory);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(managed);
+                    m_attached.put(factory, list);
+                    // Subscribe to the factory state change
+                    factory.addFactoryStateListener(this);
+                } else {
+                    list.add(managed);
+                }
+                return;
+            }
+        }
+        // If there is no matching factory, add the instance to the idle list
+        m_idle.add(managed);
+    }
+
+    /**
+     * Dispose and stop to manage all instances declared by the given bundle.
+     * @param bundle : bundle.
+     */
+    void removeInstancesFromBundle(long bundle) {
+        // Disposes instance from attached instances
+        Collection col = m_attached.keySet();
+        Iterator iterator = col.iterator();
+        List instanceToRemove = new ArrayList();
+        List factoryToRemove = new ArrayList();
+        while (iterator.hasNext()) {
+            IPojoFactory factory = (IPojoFactory) iterator.next();
+            List list = (List) m_attached.get(factory);
+            for (int i = 0; i < list.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) list.get(i);
+                if (managed.m_bundleId == bundle) {
+                    managed.dispose();
+                    instanceToRemove.add(managed);
+                }
+            }
+            if (!instanceToRemove.isEmpty()) {
+                list.removeAll(instanceToRemove);
+                if (list.isEmpty()) {
+                    factory.removeFactoryStateListener(this);
+                    factoryToRemove.add(factory);
+                }
+            }
+        }
+
+        for (int i = 0; i < factoryToRemove.size(); i++) {
+            m_attached.remove(factoryToRemove.get(i));
+        }
+
+        // Delete idle instances
+        instanceToRemove.clear();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.m_bundleId == bundle) {
+                instanceToRemove.add(managed);
+            }
+        }
+        m_idle.removeAll(instanceToRemove);
+    }
+
+    /**
+     * A new factory appears.
+     * @param factory : the new factory.
+     */
+    public synchronized void addFactory(IPojoFactory factory) {
+        List createdInstances = new ArrayList(1);
+        m_factories.add(factory);
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.match(factory)) {
+                // We have to subscribe to the factory.
+                factory.addFactoryStateListener(this);
+                if (factory.getState() == Factory.VALID) {
+                    managed.create(factory);
+                    List list = (List) m_attached.get(factory);
+                    if (list == null) {
+                        list = new ArrayList();
+                        list.add(managed);
+                        m_attached.put(factory, list);
+                    } else {
+                        list.add(managed);
+                    }
+                    createdInstances.add(managed);
+                }
+            }
+        }
+        if (!createdInstances.isEmpty()) {
+            m_idle.removeAll(createdInstances);
+        }
+    }
+
+    /**
+     * A factory is leaving.
+     * @param factory : the leaving factory
+     */
+    void removeFactory(IPojoFactory factory) {
+        factory.removeFactoryStateListener(this);
+        m_factories.remove(factory);
+        onInvalidation(factory);
+        m_attached.remove(factory);
+    }
+
+    /**
+     * The given factory becomes valid.
+     * @param factory : the factory becoming valid.
+     */
+    private void onValidation(IPojoFactory factory) {
+        List toRemove = new ArrayList();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.match(factory)) {
+                managed.create(factory);
+                List list = (List) m_attached.get(factory);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(managed);
+                    m_attached.put(factory, list);
+                } else {
+                    list.add(managed);
+                }
+                toRemove.add(managed);
+            }
+        }
+        if (!toRemove.isEmpty()) {
+            m_idle.removeAll(toRemove);
+        }
+    }
+
+    /**
+     * The given factory becomes invalid.
+     * @param factory : factory which becomes invalid.
+     */
+    private void onInvalidation(IPojoFactory factory) {
+        List instances = (List) m_attached.remove(factory);
+        if (instances != null) {
+            for (int i = 0; i < instances.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) instances.get(i);
+                managed.dispose();
+                m_idle.add(managed);
+            }
+        }
+    }
+
+    /**
+     * Factory state changed method.
+     * @param factory : factory.
+     * @param newState : new state.
+     * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int)
+     */
+    public void stateChanged(Factory factory, int newState) {
+        if (newState == Factory.VALID) {
+            onValidation((IPojoFactory) factory);
+        } else {
+            onInvalidation((IPojoFactory) factory);
+        }
+    }
+
+    /**
+     * This structure aims to manage a configuration. It stores all necessary information to create an instance and to track the factory.
+     */
+    private class ManagedInstance {
         /**
          * Configuration of the instance to create.
          */
         private Dictionary m_configuration;
 
         /**
-         * Factory name.
+         * Bundle which create the instance.
          */
-        private String m_factoryName;
+        private long m_bundleId;
+
+        /**
+         * Factory used to create the instance.
+         */
+        private IPojoFactory m_factory;
 
         /**
          * Created instance.
@@ -71,27 +258,20 @@
 
         /**
          * Constructor.
-         * 
          * @param conf : the configuration to create.
+         * @param bundle : the bundle in which the instance is declared.
          */
-        ManagedConfiguration(Dictionary conf) {
+        ManagedInstance(Dictionary conf, long bundle) {
             m_configuration = conf;
-        }
-
-        /**
-         * Return the managed configuration.
-         * @return the configuration.
-         */
-        Dictionary getConfiguration() {
-            return m_configuration;
+            m_bundleId = bundle;
         }
 
         /**
          * Return the used factory name.
          * @return the factory
          */
-        String getFactory() {
-            return m_factoryName;
+        IPojoFactory getFactory() {
+            return m_factory;
         }
 
         /**
@@ -103,215 +283,59 @@
         }
 
         /**
-         * Set the factory name.
-         * 
-         * @param name : the factory name.
+         * Test if the given factory match with the factory required by this instance. A factory matches if its name or its class name is equals to
+         * the 'component' property of the instance. Then the acceptability of the configuration is checked.
+         * @param factory : the factory to confront against the current instance.
+         * @return true if the factory match.
          */
-        void setFactory(String name) {
-            m_factoryName = name;
+        public boolean match(IPojoFactory factory) {
+            // Test factory name (and classname)
+            String component = (String) m_configuration.get("component");
+            if (factory.getName().equals(component) || factory.getClassName().equalsIgnoreCase(component)) {
+                // Test factory accessibility
+                if (factory.m_isPublic || factory.getBundleContext().getBundle().getBundleId() == m_bundleId) {
+                    // Test the configuration validity.
+                    if (factory.isAcceptable(m_configuration)) {
+                        return true;
+                    } else {
+                        m_logger.log(Logger.ERROR, "An instance can be bound to a matching factory, however the configuration seems unacceptable : "
+                                + m_configuration);
+                    }
+                }
+            }
+            return false;
         }
 
         /**
-         * Set the instance object.
-         * 
-         * @param instance : the instance
+         * Create the instance by using the given factory.
+         * @param factory : the factory to use to create the instance. The factory must match.
          */
-        void setInstance(ComponentInstance instance) {
-            m_instance = instance;
-        }
-    }
-
-    /**
-     * Configurations to create and maintains.
-     */
-    private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
-
-    /**
-     * Service Tracker tracking factories.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Constructor.
-     * 
-     * @param context : the bundle context.
-     * @param configurations : configuration set to create and maintain.
-     * @param factories : private factories.
-     */
-    public InstanceCreator(BundleContext context, Dictionary[] configurations, ComponentFactory[] factories) {
-        m_context = context;
-        m_logger = new Logger(context, "InstanceCreator" + context.getBundle().getBundleId(), Logger.WARNING);
-        
-        m_configurations = new ManagedConfiguration[configurations.length];
-        m_factories = factories;
-       
-        for (int i = 0; i < configurations.length; i++) {
-            ManagedConfiguration conf = new ManagedConfiguration(configurations[i]);
-            m_configurations[i] = conf;
-            // Get the component type name :
-            String componentType = (String) conf.getConfiguration().get("component");
-
-            boolean found = false;
-            for (int j = 0; m_factories != null && !found && j < m_factories.length; j++) {
-                if (m_factories[j].m_state == Factory.VALID && (m_factories[j].getName().equals(componentType) || (m_factories[j].getComponentClassName() != null && m_factories[j].getComponentClassName().equals(componentType)))) {
-                    createInstance(m_factories[j], conf);
-                    found = true;
-                }
+        public void create(IPojoFactory factory) {
+            try {
+                m_factory = factory;
+                m_instance = m_factory.createComponentInstance(m_configuration);
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
             }
         }
-        
-        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
-            m_factories[i].addFactoryStateListener(this);
-        }
-       
-        
-        String filter = "(&(objectclass=" + Factory.class.getName() + ")(factory.state=1))";
-        try {
-            m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
-            m_tracker.open();
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        } 
-    }
 
-    /**
-     * Create an instance using the given factory and the given configuration.
-     * 
-     * @param fact : the factory name to used.
-     * @param config : the configuration.
-     */
-    private void createInstance(Factory fact, ManagedConfiguration config) {
-        Dictionary conf = config.getConfiguration();
-        try {
-            config.setInstance(fact.createComponentInstance(conf));
-            config.setFactory(fact.getName());
-        } catch (UnacceptableConfiguration e) {
-            m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
-            stop();
-        } catch (MissingHandlerException e) {
-            m_logger.log(Logger.ERROR, "The instance creation has failed, at least one handler is missing", e);
-            stop();
-        } catch (ConfigurationException e) {
-            m_logger.log(Logger.ERROR, "The instance creation has failed, an error during the configuration has occured", e);
-            stop();
-        }
-    }
-
-    /**
-     * Stop all created instances.
-     */
-    public synchronized void stop() {
-        m_tracker.close();
-        
-        for (int i = 0; m_factories != null && i < m_factories.length; i++) {
-            m_factories[i].removeFactoryStateListener(this);
-        }
-        
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getInstance() != null) {
-                m_configurations[i].getInstance().dispose();
+        /**
+         * Dispose the current instance.
+         */
+        public void dispose() {
+            if (m_instance != null) {
+                m_instance.dispose();
             }
-            m_configurations[i].setInstance(null);
-            m_configurations[i].setFactory(null);
+            m_instance = null;
+            m_factory = null;
         }
-        
-        m_factories = null;
-        m_tracker = null;
-        m_logger = null;
-        m_configurations = null;
-    }
-
-    /**
-     * Factory state changed method.
-     * @param factory : factory.
-     * @param newState : new state.
-     * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int)
-     */
-    public void stateChanged(Factory factory, int newState) {
-        if (newState == Factory.VALID) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() == null
-                        && (m_configurations[i].getConfiguration().get("component").equals(factory.getName()) || m_configurations[i].getConfiguration().get(
-                                "component").equals(((ComponentFactory) factory).getComponentClassName()))) {
-                    Factory fact = factory;
-                    createInstance(fact, m_configurations[i]);
-                }
-            }
-            return;
-        } else {
-            // newState == INVALID
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {
-                    m_configurations[i].setInstance(null);
-                    m_configurations[i].setFactory(null);
-                }
-            }
-            return;
-        }
-    }
-
-    /**
-     * A new factory has been detected.
-     * @param ref : the factory service reference.
-     * @return true if the factory can be used to create a managed instance.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference ref) {
-        String factoryName = (String) ref.getProperty("factory.name");
-        String componentClass = (String) ref.getProperty("component.class");
-        boolean isValid = ((String) ref.getProperty("factory.state")).equals("" + Factory.VALID); 
-        Factory fact = (Factory) m_tracker.getService(ref);
-
-        boolean used = false;
-        if (isValid) {
-            for (int i = 0; i < m_configurations.length; i++) {
-                if (m_configurations[i].getInstance() == null
-                        && (m_configurations[i].getConfiguration().get("component").equals(factoryName) || m_configurations[i].getConfiguration().get("component").equals(componentClass))) {
-                    createInstance(fact, m_configurations[i]);
-                    used = true;
-                }
-            }
-        }
-        return used;
-    }
-    
-    /**
-     * A matching service has been added to the tracker.
-     * Nothing to do, as all action are computed in the adding method.
-     * @param ref : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference ref) { }
-
-    /**
-     * A used factory is modified.
-     * @param ref : modified reference.
-     * @param obj : factory object.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference ref, Object obj) { }
-
-    /**
-     * A used factory disappears.
-     * All created instance are disposed.
-     * @param ref : service reference.
-     * @param obj : factory object.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference ref, Object obj) {
-        String name = (String) ref.getProperty("factory.name");
-        if (name == null) { return; }
-        for (int i = 0; i < m_configurations.length; i++) {
-            if (m_configurations[i].getFactory() != null && m_configurations[i].getFactory().equals(name)) {
-                if (m_configurations[i].getInstance() != null) {
-                    m_configurations[i].getInstance().dispose();
-                    m_configurations[i].setInstance(null);
-                }
-                m_configurations[i].setFactory(null);
-            }
-        }
-        m_tracker.ungetService(ref);
     }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
index b310ece..01172df 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -19,7 +19,9 @@
 package org.apache.felix.ipojo;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashMap;
@@ -35,13 +37,10 @@
 import org.osgi.framework.BundleContext;
 
 /**
- * The instance manager class manages one instance of a component type. It
- * manages component lifecycle, component instance creation and handlers.
- * 
+ * The instance manager class manages one instance of a component type. It manages component lifecycle, component instance creation and handlers.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class InstanceManager implements ComponentInstance, InstanceStateListener {
-
     /**
      * Name of the component instance.
      */
@@ -51,7 +50,7 @@
      * Name of the component type implementation class.
      */
     protected String m_className;
-    
+
     /**
      * Handler list.
      */
@@ -61,12 +60,12 @@
      * Component state (STOPPED at the beginning).
      */
     protected int m_state = STOPPED;
-    
+
     /**
      * Instance State Listener List.
      */
-    protected List m_instanceListeners = null;
-    
+    protected List m_listeners = null;
+
     /**
      * Parent factory (ComponentFactory).
      */
@@ -78,12 +77,12 @@
     private BundleContext m_context;
 
     /**
-     * Map [field, handler list] storing handlers interested by the field.
+     * Map [field, field interceptor list] storing handlers interested by the field.
      */
-    private Map m_fieldRegistration = new HashMap();
-    
+    private Map m_fieldRegistration;
+
     /**
-     * Map [method identifier, handler list] storing handlers interested by the method.
+     * Map [method identifier, method interceptor list] storing handlers interested by the method.
      */
     private Map m_methodRegistration;
 
@@ -95,78 +94,89 @@
     /**
      * Instances of the components.
      */
-    private Object[] m_pojoObjects = null;
+    private List m_pojoObjects;
 
-   /**
-    * Is the component instance state changing?
-    */
-    private boolean m_inTransition = false;
-    
     /**
-     * Queue of stored state changed. 
+     * Factory method. Contains the name of the static method used to create POJO objects.
+     */
+    private String m_factoryMethod = null;
+
+    /**
+     * Is the component instance state changing?
+     */
+    private boolean m_inTransition = false;
+
+    /**
+     * Queue of stored state changed.
      */
     private List m_stateQueue = new ArrayList();
-    
+
     /**
      * Map of [field, value], storing POJO field value.
      */
-    private Map m_map = new HashMap();
+    private Map m_fields = new HashMap();
+
+    /**
+     * Map method [id=>method].
+     */
+    private Map m_methods = new HashMap();
 
     /**
      * Construct a new Component Manager.
-     * 
      * @param factory : the factory managing the instance manager
-     * @param bc : the bundle context to give to the instance
+     * @param context : the bundle context to give to the instance
      * @param handlers : handlers array
      */
-    public InstanceManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
+    public InstanceManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
         m_factory = factory;
-        m_context = bc;
+        m_context = context;
         m_handlers = handlers;
     }
 
     /**
-     * Configure the instance manager. Stop the existing handler, clear the
-     * handler list, change the metadata, recreate the handlers
-     * 
-     * @param cm : the component type metadata
+     * Configure the instance manager. Stop the existing handler, clear the handler list, change the metadata, recreate the handlers
+     * @param metadata : the component type metadata
      * @param configuration : the configuration of the instance
      * @throws ConfigurationException : occurs if the metadata are not correct
      */
-    public void configure(Element cm, Dictionary configuration) throws ConfigurationException {
-        m_className = cm.getAttribute("className");
-        
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_className = metadata.getAttribute("className");
+
         // Add the name
         m_name = (String) configuration.get("name");
-        
+
+        // Get the factory method if presents.
+        m_factoryMethod = (String) metadata.getAttribute("factory-method");
+
         // Create the standard handlers and add these handlers to the list
         for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].init(this, cm, configuration);
+            m_handlers[i].init(this, metadata, configuration);
         }
     }
 
     /**
-     * Get the description of the current instance. 
+     * Get the description of the current instance.
      * @return the instance description.
      * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
      */
     public InstanceDescription getInstanceDescription() {
         int componentState = getState();
-        InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
+        InstanceDescription desc =
+                new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
 
         if (m_pojoObjects != null) {
-            String[] objects = new String[m_pojoObjects.length];
-            for (int i = 0; i < m_pojoObjects.length; i++) {
-                objects[i] = m_pojoObjects[i].toString();
+            String[] objects = new String[m_pojoObjects.size()];
+            for (int i = 0; i < m_pojoObjects.size(); i++) {
+                objects[i] = m_pojoObjects.get(i).toString();
             }
-            instanceDescription.setCreatedObjects(objects);
+            desc.setCreatedObjects(objects);
         }
 
         Handler[] handlers = getRegistredHandlers();
         for (int i = 0; i < handlers.length; i++) {
-            instanceDescription.addHandler(handlers[i].getDescription());
+            desc.addHandler(handlers[i].getDescription());
         }
-        return instanceDescription;
+        return desc;
     }
 
     /**
@@ -174,22 +184,21 @@
      * @return the handler array of plugged handlers.
      */
     public Handler[] getRegistredHandlers() {
-        Handler[] h = new Handler[m_handlers.length];
+        Handler[] handler = new Handler[m_handlers.length];
         for (int i = 0; i < m_handlers.length; i++) {
-            h[i] = m_handlers[i].getHandler();
+            handler[i] = m_handlers[i].getHandler();
         }
-        return h;
+        return handler;
     }
 
     /**
      * Return a specified handler.
-     * 
      * @param name : class name of the handler to find or its qualified name (namespace:name)
      * @return : the handler, or null if not found
      */
     public Handler getHandler(String name) {
         for (int i = 0; i < m_handlers.length; i++) {
-            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getInstance().getFactory();
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getHandlerManager().getFactory();
             if (fact.getHandlerName().equals(name)) {
                 return m_handlers[i].getHandler();
             }
@@ -198,24 +207,83 @@
     }
 
     /**
+     * Give access to a field value to the first created pojo.
+     * This method process by analyzing both managed fields and pojo fields (by reflection).
+     * If no pojo were already created try only on managed fields.
+     * @param fieldName : field name.
+     * @return the field value, null is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName) {
+        if (m_pojoObjects == null) {
+            return getFieldValue(fieldName, null);
+        } else {
+            return getFieldValue(fieldName, m_pojoObjects.get(0)); // Use the first pojo.
+        }
+    }
+
+    /**
+     * Give access to a field value to the given created pojo.
+     * This method process by analyzing both managed fields and pojo fields (by reflection).
+     * If the given pojo is null, try only on managed fields.
+     * @param fieldName : field name.
+     * @param pojo : the pojo on which computing field value.
+     * @return the field value, null is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName, Object pojo) {
+        Object setByContainer = null;
+        
+        if (m_fields != null) {
+            setByContainer = m_fields.get(fieldName);
+        }
+        
+        if (setByContainer == null && pojo != null) { // In the case of no given pojo, return null.
+            // If null either the value was not already set or has the null value.
+            try {
+                Field field = pojo.getClass().getDeclaredField(fieldName);
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+                return field.get(pojo);
+            } catch (SecurityException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (NoSuchFieldException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalArgumentException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalAccessException e) {
+                m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            }
+            return null;
+        } else {
+            return setByContainer;
+        }
+    }
+
+    /**
      * Start the instance manager.
      */
     public synchronized void start() {
         if (m_state != STOPPED) { // Instance already started
             return;
-        } 
-        
+        }
+
         for (int i = 0; i < m_handlers.length; i++) {
             m_handlers[i].addInstanceStateListener(this);
-            m_handlers[i].start();
+            try {
+                m_handlers[i].start();
+            } catch (IllegalStateException e) {
+                m_factory.getLogger().log(Logger.ERROR, e.getMessage());
+                stop();
+                throw e;
+            }
         }
-        
+
         for (int i = 0; i < m_handlers.length; i++) {
-            
             if (m_handlers[i].getState() != VALID) {
                 setState(INVALID);
                 return;
             }
+
         }
         setState(VALID);
     }
@@ -227,26 +295,27 @@
         if (m_state == STOPPED) {
             return;
         } // Instance already stopped
-        
+
         setState(INVALID);
-        
+
+        m_state = STOPPED;
+
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].removeInstanceStateListener(this);
             m_handlers[i].stop();
         }
-        
+
         m_pojoObjects = null;
 
-        m_state = STOPPED;
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        if (m_listeners != null) {
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
             }
         }
     }
-    
-    /** 
+
+    /**
      * Dispose the instance.
      * @see org.apache.felix.ipojo.ComponentInstance#dispose()
      */
@@ -254,100 +323,79 @@
         if (m_state > STOPPED) { // Valid or invalid
             stop();
         }
-        
+
         m_state = DISPOSED;
-        
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-            }
-            m_instanceListeners = null;
+
+        for (int i = 0; m_listeners != null && i < m_listeners.size(); i++) {
+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
         }
-        
-        m_factory.disposed(this);
-        
+        m_listeners = null;
+
         for (int i = m_handlers.length - 1; i > -1; i--) {
             m_handlers[i].dispose();
         }
-        
-        m_map.clear();
-        m_handlers = new HandlerManager[0];
-        m_fieldRegistration = new HashMap();
-        m_methodRegistration = new HashMap();
-        m_clazz = null;
-        m_inTransition = false;
-    }
-    
-    /**
-     * Kill the current instance.
-     * Only the factory of this instance can call this method.
-     */
-    protected void kill() {
-        if (m_state > STOPPED) {
-            stop();
-        }
-        if (m_instanceListeners != null) {
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
-            }
-            m_instanceListeners = null;
-        }
 
-        // Cleaning
-        m_state = DISPOSED;
-        
-        for (int i = 0; i < m_handlers.length; i++) {
-            m_handlers[i].dispose();
-        }
-        
-        m_map.clear();
         m_handlers = new HandlerManager[0];
+        m_factory.disposed(this);
+        m_fields.clear();
         m_fieldRegistration = new HashMap();
         m_methodRegistration = new HashMap();
         m_clazz = null;
         m_inTransition = false;
-        
     }
-    
+
     /**
-     * Set the state of the component instance.
-     * if the state changed call the stateChanged(int) method on the handlers.
-     * This method has a reentrant mechanism. If in the flow of the first call the method is called another times, 
-     * the second call is stored and executed after the first one is finished.
+     * Set the state of the component instance. if the state changed call the stateChanged(int) method on the handlers. This method has a reentrant
+     * mechanism. If in the flow of the first call the method is called another times, the second call is stored and executed after the first one is
+     * finished.
      * @param state : the new state
      */
     public synchronized void setState(int state) {
         if (m_inTransition) {
-            m_stateQueue.add(new Integer(state)); 
+            m_stateQueue.add(new Integer(state));
             return;
         }
-        
+
         if (m_state != state) {
             m_inTransition = true;
 
             if (state > m_state) {
                 // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
                 m_state = state;
-                for (int i = 0; i < m_handlers.length; i++) {
-                    m_handlers[i].getHandler().stateChanged(state);
+                try {
+                    for (int i = 0; i < m_handlers.length; i++) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    m_stateQueue.clear();
+                    stop();
+                    return;
                 }
             } else {
                 // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
                 m_state = state;
-                for (int i = m_handlers.length - 1; i > -1; i--) {
-                    m_handlers[i].getHandler().stateChanged(state);
+                try {
+                    for (int i = m_handlers.length - 1; i > -1; i--) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    m_stateQueue.clear();
+                    stop();
+                    return;
                 }
             }
-            
-            if (m_instanceListeners != null) {
-                for (int i = 0; i < m_instanceListeners.size(); i++) {
-                    ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+
+            if (m_listeners != null) {
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);
                 }
             }
         }
-        
+
         m_inTransition = false;
-        if (! m_stateQueue.isEmpty()) {
+        if (!m_stateQueue.isEmpty()) {
             int newState = ((Integer) (m_stateQueue.remove(0))).intValue();
             setState(newState);
         }
@@ -370,18 +418,18 @@
     public boolean isStarted() {
         return m_state > STOPPED;
     }
-    
+
     /**
      * Register an instance state listener.
      * @param listener : listener to register.
      * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
-    public void addInstanceStateListener(InstanceStateListener listener) {
-        if (m_instanceListeners == null) {
-            m_instanceListeners = new ArrayList();
+    public synchronized void addInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners == null) {
+            m_listeners = new ArrayList();
         }
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.add(listener);
+        synchronized (m_listeners) {
+            m_listeners.add(listener);
         }
     }
 
@@ -390,12 +438,12 @@
      * @param listener : listener to unregister.
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
-    public void removeInstanceStateListener(InstanceStateListener listener) {
-        if (m_instanceListeners != null) {
-            synchronized (m_instanceListeners) {
-                m_instanceListeners.remove(listener);
-                if (m_instanceListeners.size() == 0) {
-                    m_instanceListeners = null;
+    public synchronized void removeInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners != null) {
+            synchronized (m_listeners) {
+                m_listeners.remove(listener);
+                if (m_listeners.isEmpty()) {
+                    m_listeners = null;
                 }
             }
         }
@@ -424,129 +472,186 @@
     }
 
     /**
-     * Add an instance to the created instance list.
-     * @param o : the instance to add
-     */
-    private synchronized void addInstance(Object o) {
-        if (m_pojoObjects != null) {
-            Object[] newInstances = new Object[m_pojoObjects.length + 1];
-            System.arraycopy(m_pojoObjects, 0, newInstances, 0, m_pojoObjects.length);
-            newInstances[m_pojoObjects.length] = o;
-            m_pojoObjects = newInstances;
-        } else {
-            m_pojoObjects = new Object[] { o };
-        }
-    }
-
-    /**
      * Get the array of object created by the instance.
      * @return the created instance of the component instance.
      */
     public Object[] getPojoObjects() {
-        return m_pojoObjects;
+        if (m_pojoObjects == null) {
+            return null;
+        }
+        return m_pojoObjects.toArray(new Object[m_pojoObjects.size()]);
     }
 
     /**
-     * Delete the created instance (remove it from the list, to allow the
-     * garbage collector to eat the instance).
-     * 
-     * @param o : the instance to delete
-     */
-    public synchronized void deletePojoObject(Object o) {
-        int idx = -1;
-        for (int i = 0; i < m_pojoObjects.length; i++) {
-            if (m_pojoObjects[i] == o) {
-                idx = i;
-                break;
-            }
-        }
-
-        if (idx >= 0) {
-            if ((m_pojoObjects.length - 1) == 0) {
-                m_pojoObjects = null;
-            } else {
-                Object[] newInstances = new Object[m_pojoObjects.length - 1];
-                System.arraycopy(m_pojoObjects, 0, newInstances, 0, idx);
-                if (idx < newInstances.length) {
-                    System.arraycopy(m_pojoObjects, idx + 1, newInstances, idx, newInstances.length - idx);
-                }
-                m_pojoObjects = newInstances;
-            }
-        }
-    }
-
-    /**
-     * Create an instance of the component. This method need to be called one
-     * time only for singleton provided service
-     * 
+     * Create an instance of the component. This method need to be called one time only for singleton provided service
      * @return a new instance
      */
     public Object createPojoObject() {
-
         if (m_clazz == null) {
             load();
         }
+
         Object instance = null;
-        try {
-            // Try to find if there is a constructor with a bundle context as
-            // parameter :
+
+        if (m_factoryMethod == null) {
+            // No factory-method, we use the constructor.
             try {
-                Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class, BundleContext.class });
-                constructor.setAccessible(true);
-                instance = constructor.newInstance(new Object[] { this, m_context });
+                // Try to find if there is a constructor with a bundle context as parameter :
+                try {
+                    Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class, BundleContext.class });
+                    if (! cst.isAccessible()) {
+                        cst.setAccessible(true);
+                    }
+                    Object[] args = new Object[] { this, m_context };
+                    onEntry(null, m_className,  new Object[] {m_context});
+                    instance = cst.newInstance(args);
+                    onExit(null, m_className, instance);
+                } catch (NoSuchMethodException e) {
+                    // Create an instance if no instance are already created with <init>()BundleContext
+                    if (instance == null) {
+                        Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class });
+                        if (! cst.isAccessible()) {
+                            cst.setAccessible(true);
+                        }
+                        Object[] args = new Object[] {this};
+                        onEntry(null, m_className, new Object[0]);
+                        instance = cst.newInstance(args);
+                        onExit(null, m_className, instance);
+                    }
+                }
+            } catch (IllegalAccessException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor is not accessible : " + e.getMessage());
+                stop();
+            } catch (SecurityException e) {
+                m_factory.getLogger().log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> The Component Instance is not accessible (security reason) : "
+                                                  + e.getMessage());
+                stop();
+            } catch (InvocationTargetException e) {
+                m_factory.getLogger().log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> Cannot invoke the constructor method (illegal target) : "
+                                                  + e.getTargetException().getMessage());
+                onError(null, m_className, e.getTargetException());
+                stop();
             } catch (NoSuchMethodException e) {
-                instance = null;
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
+                stop();
+            } catch (IllegalArgumentException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+                stop();
+            } catch (InstantiationException e) {
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+                stop();
+            }
+        } else {
+            try {
+                // Build the pojo object with the factory-method.
+                Method factory = null;
+                // Try with the bundle context
+                try {
+                    factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[] { BundleContext.class });
+                    if (! factory.isAccessible()) {
+                        factory.setAccessible(true);
+                    }
+                    Object[] args = new Object[] { m_context };
+                    onEntry(null, m_className, args);
+                    instance = factory.invoke(null, new Object[] { m_context });
+                } catch (NoSuchMethodException e1) {
+                    // Try without the bundle context
+                    try {
+                        factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[0]);
+                        if (! factory.isAccessible()) {
+                            factory.setAccessible(true);
+                        }
+                        Object[] args = new Object[0];
+                        onEntry(null, m_className, args);
+                        instance = factory.invoke(null, args);
+                    } catch (NoSuchMethodException e2) {
+                        // Error : factory-method not found
+                        m_factory.getLogger().log(
+                                                  Logger.ERROR,
+                                                  "["
+                                                          + m_name
+                                                          + "] createInstance -> Cannot invoke the factory-method (method not found) : "
+                                                          + e2.getMessage());
+                        stop();
+                    }
+                }
+
+                // Now call the setInstanceManager method.
+                Method method = instance.getClass().getDeclaredMethod("_setInstanceManager", new Class[] { InstanceManager.class });
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+                method.invoke(instance, new Object[] { this });
+                onExit(null, m_className, instance);
+
+            } catch (SecurityException e) {
+                // Error : invocation failed
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (IllegalArgumentException e) {
+                // Error : arguments mismatch
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (IllegalAccessException e) {
+                // Error : illegal access
+                m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+                stop();
+            } catch (InvocationTargetException e) {
+                // Error : invocation failed
+                m_factory.getLogger().log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The factory-method returns an exception : " + e.getTargetException());
+                onError(null, m_className, e.getTargetException());
+                stop();
+            } catch (NoSuchMethodException e) {
+                // Error : _setInstanceManager method is missing
+                m_factory.getLogger()
+                        .log(
+                             Logger.ERROR,
+                             "["
+                                     + m_name
+                                     + "] createInstance -> Cannot invoke the factory-method (the _setInstanceManager method does not exist) : "
+                                     + e.getMessage());
+                stop();
             }
 
-            // Create an instance if no instance are already created with
-            // <init>()BundleContext
-            if (instance == null) {
-                Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class });
-                constructor.setAccessible(true);
-                instance = constructor.newInstance(new Object[] { this });
+        }
+
+        // Register the new instance in not already present.
+        if (m_pojoObjects == null) {
+            m_pojoObjects = new ArrayList(1);
+        }
+        if (!m_pojoObjects.contains(instance)) {
+            m_pojoObjects.add(instance);
+            // Call createInstance on Handlers :
+            for (int i = 0; i < m_handlers.length; i++) {
+                ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(instance);
             }
-
-        } catch (InstantiationException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance cannot be instancied : " + e.getMessage());
-            stop();
-        } catch (IllegalAccessException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible : " + e.getMessage());
-            stop();
-        } catch (SecurityException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
-            stop();
-        } catch (InvocationTargetException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getTargetException().getMessage());
-            e.printStackTrace();
-            stop();
-        } catch (NoSuchMethodException e) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
-            stop();
-        }
-        if (instance == null) {
-            m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot create the instance");
-            stop();
         }
 
-        // Register the new instance
-        addInstance(instance);
-        // Call createInstance on Handlers :
-        for (int i = 0; i < m_handlers.length; i++) {
-            ((PrimitiveHandler) m_handlers[i].getHandler()).objectCreated(instance);
-        }
         return instance;
     }
 
     /**
-     * Get the first object created by the instance.
-     * If no object created, create and return one object.
+     * Get the first object created by the instance. If no object created, create and return one object.
      * @return the instance of the component instance to use for singleton component
      */
     public synchronized Object getPojoObject() {
         if (m_pojoObjects == null) {
-            createPojoObject();
+            return createPojoObject();
         }
-        return m_pojoObjects[0];
+        return m_pojoObjects.get(0);
     }
 
     /**
@@ -561,134 +666,219 @@
     }
 
     /**
-     * Register an handler. The handler will be notified of event on each field
-     * given in the list.
-     * 
-     * @param h : the handler to register
+     * Register an handler. The handler will be notified of event on each field given in the list.
+     * @param handler : the handler to register
      * @param fields : the field metadata list
      * @param methods : the method metadata list
+     * @deprecated use register(FieldMetadata fm, FieldInterceptor fi) and register(MethodMetadata mm, MethodInterceptor mi) instead. 
      */
-    public void register(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
+    public void register(PrimitiveHandler handler, FieldMetadata[] fields, MethodMetadata[] methods) {
         for (int i = 0; fields != null && i < fields.length; i++) {
-            if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
-                m_fieldRegistration.put(fields[i].getFieldName(), new PrimitiveHandler[] { h });
+            register(fields[i], handler);
+        }
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            register(methods[i], handler);
+        }
+
+    }
+    
+    /**
+     * Register a field interceptor.
+     * @param field : intercepted field
+     * @param interceptor : interceptor
+     */
+    public void register(FieldMetadata field, FieldInterceptor interceptor) {
+        if (m_fieldRegistration == null) {
+            m_fieldRegistration = new HashMap();
+            m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
+        } else {
+            FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(field.getFieldName());
+            if (list == null) {
+                m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
             } else {
-                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
                 for (int j = 0; j < list.length; j++) {
-                    if (list[j] == h) {
+                    if (list[j] == interceptor) {
                         return;
                     }
                 }
-                PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
+                FieldInterceptor[] newList = new FieldInterceptor[list.length + 1];
                 System.arraycopy(list, 0, newList, 0, list.length);
-                newList[list.length] = h;
-                m_fieldRegistration.put(fields[i].getFieldName(), newList);
+                newList[list.length] = interceptor;
+                m_fieldRegistration.put(field.getFieldName(), newList);
             }
         }
-        for (int i = 0; methods != null && i < methods.length; i++) {
-            if (m_methodRegistration == null) { 
-                m_methodRegistration = new HashMap();
-                m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
-            } else { 
-                PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
-                if (list == null) {
-                    m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
-                } else {
-                    for (int j = 0; j < list.length; j++) {
-                        if (list[j] == h) {
-                            return;
-                        }
+    }
+    
+    /**
+     * Register a method interceptor.
+     * @param method : intercepted method
+     * @param interceptor : interceptor
+     */
+    public void register(MethodMetadata method, MethodInterceptor interceptor) {
+        if (m_methodRegistration == null) {
+            m_methodRegistration = new HashMap();
+            m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+        } else {
+            MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(method.getMethodIdentifier());
+            if (list == null) {
+                m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+            } else {
+                for (int j = 0; j < list.length; j++) {
+                    if (list[j] == interceptor) {
+                        return;
                     }
-                    PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
-                    System.arraycopy(list, 0, newList, 0, list.length);
-                    newList[list.length] = h;
-                    m_methodRegistration.put(methods[i].getMethodIdentifier(), newList);
                 }
+                MethodInterceptor[] newList = new MethodInterceptor[list.length + 1];
+                System.arraycopy(list, 0, newList, 0, list.length);
+                newList[list.length] = interceptor;
+                m_methodRegistration.put(method.getMethodIdentifier(), newList);
             }
         }
-        
     }
 
     /**
-     * This method is called by the manipulated class each time that a GETFIELD
-     * instruction is found. The method ask to each handler which value need to
-     * be returned.
-     * 
-     * @param fieldName : the field name on which the GETFIELD instruction is
-     * called
-     * @return the value decided by the last asked handler (throw a warning if
-     * two fields decide two different values)
+     * This method is called by the manipulated class each time that a GETFIELD instruction is found. The method ask to each handler which value need
+     * to be returned.
+     * @param pojo : the pojo object on which the field was get
+     * @param fieldName : the field name on which the GETFIELD instruction is called
+     * @return the value decided by the last asked handler (throw a warning if two fields decide two different values)
      */
-    public Object getterCallback(String fieldName) {
-        Object initialValue = m_map.get(fieldName);
+    public Object onGet(Object pojo, String fieldName) {
+        Object initialValue = m_fields.get(fieldName);
         Object result = initialValue;
         // Get the list of registered handlers
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+
+        FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
         for (int i = 0; list != null && i < list.length; i++) {
-            Object handlerResult = list[i].getterCallback(fieldName, initialValue);
+            Object handlerResult = list[i].onGet(null, fieldName, initialValue);
             if (handlerResult == initialValue) {
                 continue; // Non-binding case (default implementation).
             } else {
                 if (result != initialValue) {
-                    if ((handlerResult != null && ! handlerResult.equals(result)) || (result != null && handlerResult == null)) {
-                        m_factory.getLogger().log(Logger.WARNING, "A conflict was detected on the injection of " + fieldName + " - return the last value from " + list[i].getInstance().getInstanceName());
+                    if ((handlerResult != null && !handlerResult.equals(result)) || (result != null && handlerResult == null)) {
+                        m_factory.getLogger().log(
+                                                  Logger.WARNING,
+                                                  "A conflict was detected on the injection of "
+                                                          + fieldName);
                     }
                 }
                 result = handlerResult;
             }
         }
-        
-        if ((result != null && ! result.equals(initialValue)) || (result == null && initialValue != null)) {
+
+        if ((result != null && !result.equals(initialValue)) || (result == null && initialValue != null)) {
             // A change occurs => notify the change
-            m_map.put(fieldName, result);
+            m_fields.put(fieldName, result);
             for (int i = 0; list != null && i < list.length; i++) {
-                list[i].setterCallback(fieldName, result);
+                list[i].onSet(null, fieldName, result);
             }
         }
-        
-        return result;        
+
+        return result;
     }
-    
+
     /**
      * Dispatch entry method event on registered handler.
+     * @param pojo : the pojo object on which method is invoked.
      * @param methodId : method id
+     * @param args : argument array
      */
-    public void entryCallback(String methodId) {
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+    public void onEntry(Object pojo, String methodId, Object[] args) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
-            list[i].entryCallback(methodId);
+            list[i].onEntry(pojo, method, args);
         }
     }
 
     /**
-     * Dispatch exit method event on registered handler.
-     * The given returned object is an instance of Exception if the method has launched an exception.
+     * Dispatch exit method event on registered handler. The given returned object is an instance of Exception if the method has launched an
+     * exception. If the given object is null, either the method returns void, either the method has returned null.
+     * @param pojo : the pojo object on which the method was invoked
+     * @param methodId : method id
+     * @param result : returned object.
+     */
+    public void onExit(Object pojo, String methodId, Object result) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onExit(pojo, method, result);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
+        }
+    }
+
+    /**
+     * Dispatch error method event on registered handler. The given returned object is an instance of Exception if the method has thrown an exception.
      * If the given object is null, either the method returns void, either the method has returned null.
+     * @param pojo : the pojo object on which the method was invoked
      * @param methodId : method id
-     * @param e : returned object.
+     * @param error : throwable object.
      */
-    public void exitCallback(String methodId, Object e) {
-        PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+    public void onError(Object pojo, String methodId, Throwable error) {        
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Method method = getMethodById(methodId);
         for (int i = 0; list != null && i < list.length; i++) {
-            list[i].exitCallback(methodId, e);
+            list[i].onError(pojo, method, error);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
         }
     }
 
     /**
-     * This method is called by the manipulated class each time that a PUTFILED
-     * instruction is found. the method send to each handler the new value.
-     * 
-     * @param fieldName : the field name on which the PUTFIELD instruction is
-     * called
+     * Get method object by id.
+     * @param methodId : method id
+     * @return : the method object or null if the method cannot be found.
+     */
+    private Method getMethodById(String methodId) {
+        Method method = (Method) m_methods.get(methodId);
+        if (method == null) {
+            Method[] mets = m_clazz.getDeclaredMethods();
+            for (int i = 0; i < mets.length; i++) {
+                // Check if the method was not already computed. If not, compute the Id and check.
+                if (!m_methods.containsValue(mets[i]) && (MethodMetadata.computeMethodId(mets[i]).equals(methodId))) {
+                    // Store the new methodId
+                    m_methods.put(methodId, mets[i]);
+                    return mets[i];
+                }
+            }
+            // If not found, it is a constructor, return null in this case.
+            if (methodId.equals(m_clazz.getName())) {
+                // Constructor.
+                return null;
+            }
+            // Cannot happen
+            m_factory.getLogger().log(Logger.ERROR, "A methodID cannot be associate with a POJO method : " + methodId);
+            return null;
+        } else {
+            return method;
+        }
+    }
+
+    /**
+     * This method is called by the manipulated class each time that a PUTFILED instruction is found. the method send to each handler the new value.
+     * @param pojo : the pojo object on which the field was set
+     * @param fieldName : the field name on which the PUTFIELD instruction is called
      * @param objectValue : the value of the field
      */
-    public void setterCallback(String fieldName, Object objectValue) {
-        Object o = m_map.get(fieldName);
-        if ((o != null && ! o.equals(objectValue)) || (o == null && objectValue != null)) {
-            m_map.put(fieldName, objectValue);
-            PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+    public void onSet(Object pojo, String fieldName, Object objectValue) {
+        Object value = m_fields.get(fieldName);
+        if ((value != null && !value.equals(objectValue)) || (value == null && objectValue != null)) {
+            m_fields.put(fieldName, objectValue);
+            FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
             for (int i = 0; list != null && i < list.length; i++) {
-                list[i].setterCallback(fieldName, objectValue);
+                list[i].onSet(null, fieldName, objectValue);
             }
         }
     }
@@ -701,11 +891,11 @@
     public BundleContext getContext() {
         return m_context;
     }
-    
+
     public BundleContext getGlobalContext() {
         return ((IPojoContext) m_context).getGlobalContext();
     }
-    
+
     public ServiceContext getLocalServiceContext() {
         return ((IPojoContext) m_context).getServiceContext();
     }
@@ -748,15 +938,16 @@
     }
 
     /**
-     * State Change listener callback.
-     * This method is notified at each time a plugged handler becomes invalid.
-     * @param instance : changing instance 
+     * State Change listener callback. This method is notified at each time a plugged handler becomes invalid.
+     * @param instance : changing instance
      * @param newState : new state
      * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
      */
     public synchronized void stateChanged(ComponentInstance instance, int newState) {
-        if (m_state <= STOPPED) { return; }
-        
+        if (m_state <= STOPPED) {
+            return;
+        }
+
         // Update the component state if necessary
         if (newState == INVALID && m_state == VALID) {
             // Need to update the state to UNRESOLVED
@@ -766,36 +957,35 @@
         if (newState == VALID && m_state == INVALID) {
             // An handler becomes valid => check if all handlers are valid
             for (int i = 0; i < m_handlers.length; i++) {
-                if (m_handlers[i].getState() != VALID) { return; }
+                if (m_handlers[i].getState() != VALID) {
+                    return;
+                }
             }
             setState(VALID);
             return;
-        }        
+        }
     }
-    
+
     /**
-     * Get the list of registered fields.
-     * This method is invoked by the POJO itself.
+     * Get the list of registered fields. This method is invoked by the POJO itself.
      * @return the set of registered fields.
      */
     public Set getRegistredFields() {
-        if (m_fieldRegistration != null) {
-            return m_fieldRegistration.keySet();
-        } else {
+        if (m_fieldRegistration == null) {
             return null;
         }
+        return m_fieldRegistration.keySet();
     }
-    
+
     /**
-     * Get the list of registered methods.
-     * This method is invoked by the POJO itself.
+     * Get the list of registered methods. This method is invoked by the POJO itself.
      * @return the set of registered methods.
      */
     public Set getRegistredMethods() {
-        if (m_methodRegistration != null) {
-            return m_methodRegistration.keySet();
-        } else {
+        if (m_methodRegistration == null) {
             return null;
+        } else {
+            return m_methodRegistration.keySet();
         }
     }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
new file mode 100644
index 0000000..951452f
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
@@ -0,0 +1,69 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+import java.lang.reflect.Method;

+

+/**

+* Method interceptor.

+* A class implementing this interface is able to be notified of method invocation.

+* The listener need to be register on the instance manager. 

+* For event are send to the listener : before the method entry, after the method returns, 

+* when an error is thrown by the method, and before the after either a returns or an error (finally) 

+* 

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

+*/

+public interface MethodInterceptor {

+    

+    /**

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

+     * @param pojo : pojo on which the method is called.

+     * @param method : method invoked.

+     * @param args arguments array.

+     */

+    void onEntry(Object pojo, Method method, Object[] args);

+

+    /**

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

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

+     * You must not modified the returned object.

+     * @param pojo : the pojo on which the method exits.

+     * @param method : exiting method.

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

+     */

+    void onExit(Object pojo, Method method, Object returnedObj);

+    

+    /**

+     * This method is called when the execution throw an exception in the given method.

+     * @param pojo : the pojo on which the method was accessed.

+     * @param method : invoked method.

+     * @param throwable : the thrown exception

+     */

+    void onError(Object pojo, Method method, Throwable throwable);

+    

+    /**

+     * This method is called when the execution of a method will terminate : 

+     * just before to throw an exception or before to return.

+     * OnError or OnExit was already called.

+     * @param pojo : the pojo on which the method was accessed.

+     * @param method : invoked method.

+     */

+    void onFinally(Object pojo, Method method);

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
index 7e90e43..3ba91b4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
@@ -42,6 +42,7 @@
      * @param missing : list of missing handlers.

      */

     public MissingHandlerException(List missing) {

+        super();

         m_message = "Missing handlers : ";

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

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

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
index 22ce37c..797d02e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/Nullable.java
@@ -1,28 +1,28 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo;
-
-/**
- * A Nullable object must implement this interface.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface Nullable {
-    // Nothing
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo;

+

+/**

+ * A Nullable object must implement this interface.

+ * 

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

+ */

+public interface Nullable {

+    // Nothing

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
index 45034a2..501050c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
@@ -22,7 +22,6 @@
 import java.io.InputStream;

 import java.util.Dictionary;

 

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

 import org.osgi.framework.Bundle;

 import org.osgi.framework.BundleContext;

 import org.osgi.framework.BundleException;

@@ -85,7 +84,11 @@
     public PolicyServiceContext(BundleContext global, ServiceContext local, int policy) {

         m_global = global;

         m_local = local;

-        m_policy = policy;

+        if (m_local == null) {

+            m_policy = GLOBAL;

+        } else {

+            m_policy = policy;

+        }

     }

 

     /**

@@ -137,23 +140,7 @@
             case LOCAL_AND_GLOBAL:

                 ServiceReference[] refLocal = m_local.getAllServiceReferences(clazz, filter);

                 ServiceReference[] refGlobal = m_global.getAllServiceReferences(clazz, filter);

-                if (refLocal != null && refGlobal != null) {

-                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];

-                    int j = 0;

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

-                        refs[j] = refLocal[i];

-                        j++;

-                    }

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

-                        refs[j] = refGlobal[i];

-                        j++;

-                    }

-                    return refs;

-                } else if (refLocal != null && refGlobal == null) {

-                    return refLocal;

-                } else {

-                    return refGlobal;

-                }

+                return computeServiceReferencesFromBoth(refLocal, refGlobal);

             default:

                 return null;

         }

@@ -166,7 +153,7 @@
      * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)

      */

     public Object getService(ServiceReference ref) {

-        switch(m_policy) {

+        switch(m_policy) { // NOPMD No break needed as we return in each branch.

             case LOCAL:

                 // The reference comes from the local scope

                 return m_local.getService(ref);

@@ -174,8 +161,7 @@
                 // The reference comes from the global registry

                 return m_global.getService(ref);

             case LOCAL_AND_GLOBAL:

-                if (ref instanceof org.apache.felix.ipojo.composite.ServiceReferenceImpl) {

-                    // The reference comes from a composite, i.e. necessary the local composite

+                if (ref instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {

                     return m_local.getService(ref);

                 } else {

                     return m_global.getService(ref);

@@ -192,17 +178,17 @@
      * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)

      */

     public ServiceReference getServiceReference(String clazz) {

-        switch (m_policy) {

+        switch (m_policy) { // NOPMD No break needed as we return in each branch.

             case LOCAL:

                 return m_local.getServiceReference(clazz);

             case GLOBAL:

                 return m_global.getServiceReference(clazz);

             case LOCAL_AND_GLOBAL:

                 ServiceReference refLocal = m_local.getServiceReference(clazz);

-                if (refLocal != null) {

-                    return refLocal;

+                if (refLocal == null) {

+                    return m_global.getServiceReference(clazz);

                 } else {

-                    return m_global.getServiceReference(clazz); 

+                    return refLocal;

                 }

             default:

                 return null;

@@ -226,28 +212,31 @@
             case LOCAL_AND_GLOBAL:

                 ServiceReference[] refLocal = m_local.getServiceReferences(clazz, filter);

                 ServiceReference[] refGlobal = m_global.getServiceReferences(clazz, filter);

-                if (refLocal != null && refGlobal != null) {

-                    ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];

-                    int j = 0;

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

-                        refs[j] = refLocal[i];

-                        j++;

-                    }

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

-                        refs[j] = refGlobal[i];

-                        j++;

-                    }

-                    return refs;

-                } else if (refLocal != null && refGlobal == null) {

-                    return refLocal;

-                } else {

-                    return refGlobal;

-                }

+                return computeServiceReferencesFromBoth(refLocal, refGlobal);

             default:

                 return null;

         }

 

     }

+    

+    /**

+     * Compute the service reference array from the two given set of service references.

+     * @param refLocal : local references

+     * @param refGlobal : global references

+     * @return the set of service reference

+     */

+    private ServiceReference[] computeServiceReferencesFromBoth(ServiceReference[] refLocal, ServiceReference[] refGlobal) {

+        if (refLocal == null) {

+            return refGlobal; // If refGlobal is null, return null, else return refGlobal

+        } else if (refGlobal == null) { // refLocal != null && refGlobal == null

+            return refLocal;

+        } else { // Both refGlobal and refLocal are not null

+            ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];

+            System.arraycopy(refLocal, 0, refs, 0, refLocal.length);

+            System.arraycopy(refGlobal, 0, refs, refLocal.length, refGlobal.length);

+            return refs;

+        }        

+    }

 

     /**

      * This method is not supported.

@@ -294,7 +283,7 @@
      * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)

      */

     public boolean ungetService(ServiceReference reference) {

-        if (reference instanceof ServiceReferenceImpl) {

+        if (reference instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {

             return m_local.ungetService(reference);

         } else {

             return m_global.ungetService(reference);

@@ -343,12 +332,12 @@
 

     /**

      * Get the bundle object with the given id.

-     * @param id : bundle id

+     * @param bundleId : bundle id

      * @return the bundle object

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

      */

-    public Bundle getBundle(long id) {

-        return m_global.getBundle(id);

+    public Bundle getBundle(long bundleId) {

+        return m_global.getBundle(bundleId);

     }

 

     /**

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
index 25a9eda..8add263 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
@@ -18,6 +18,12 @@
  */

 package org.apache.felix.ipojo;

 

+import java.lang.reflect.Method;

+

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

+import org.apache.felix.ipojo.parser.PojoMetadata;

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

+

 

 

 /**

@@ -25,7 +31,7 @@
 * 

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

 */

-public abstract class PrimitiveHandler extends Handler {

+public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor {

     

     /**

      * "Primitive" Handler type (value).

@@ -37,20 +43,45 @@
      */

     private InstanceManager m_manager;

     

+    

+    /**

+     * Factory of the instance manager. 

+     */

+    private ComponentFactory m_factory;

+    

     /**

      * Attach the current handler to the given instance.

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

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

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

      */

-    protected final void attach(ComponentInstance im) {

-        m_manager = (InstanceManager) im;

-        setLogger(m_manager.getFactory().getLogger());

+    protected final void attach(ComponentInstance manager) {

+        m_manager = (InstanceManager) manager;

+    }

+    

+    public final void setFactory(Factory factory) {

+        m_factory = (ComponentFactory) factory;

+    }

+    

+    public Logger getLogger() {

+        return m_factory.getLogger();

     }

     

     public InstanceManager getInstanceManager() {

         return m_manager;

     }

     

+    public ComponentFactory getFactory() {

+        return m_factory;

+    }

+    

+    public Element[] getMetadata() {

+        return null;

+    }

+    

+    public PojoMetadata getPojoMetadata() {

+        return m_factory.getPojoMetadata();

+    }

+    

     /**

      * Get a plugged handler of the same container.

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

@@ -65,45 +96,76 @@
     

     /**

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

+     * @param pojo : the pojo object setting the value

      * @param fieldName : the field name

      * @param value : the value passed to the field

      */

-    public void setterCallback(String fieldName, Object value) {

-        return;

+    public void onSet(Object pojo, String fieldName, Object value) {

+        // Nothing do do in the default implementation

     }

 

     /**

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

+     * @param pojo : the pojo object getting the value

      * @param fieldName : the field name

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

      * @return : the managed value of the field

      */

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

+    public Object onGet(Object pojo, String fieldName, Object value) {

         return value;

     }

     

     /**

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

-     * @param methodId : the method identifier

+     * @param pojo : pojo on which the method is called.

+     * @param method : method invoked.

+     * @param args arguments array.

      */

-    public void entryCallback(String methodId) { }

+    public void onEntry(Object pojo, Method method, Object[] args) { 

+        // Nothing do do in the default implementation

+    }

 

     /**

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

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

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

      * You must not modified the returned object.

-     * @param methodId : the method identifier

+     * @param pojo : the pojo on which the method exits.

+     * @param method : exiting method.

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

      */

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

+    public void onExit(Object pojo, Method method, Object returnedObj) { 

+        // Nothing do do in the default implementation

+    }

+    

+    /**

+     * This method is called when the execution throw an exception in the given method.

+     * @param pojo : the pojo on which the method was accessed.

+     * @param method : invoked method.

+     * @param throwable : the thrown exception

+     */

+    public void onError(Object pojo, Method method, Throwable throwable) {

+        // Nothing do do in the default implementation

+    }

+    

+    /**

+     * This method is called when the execution of a method will terminate : 

+     * just before to throw an exception or before to return.

+     * OnError or OnExit was already called.

+     * @param pojo : the pojo on which the method was accessed.

+     * @param method : invoked method.

+     */

+    public void onFinally(Object pojo, Method method) {

+        // Nothing do do in the default implementation

+    }

     

     /**

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

      * before someone can use it.

      * @param instance : the created instance

      */

-    public void objectCreated(Object instance) { }

+    public void onCreation(Object instance) { 

+        // Nothing do do in the default implementation

+    }

     

     

 

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
similarity index 66%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
index 1e6c94f..feb86ba 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
@@ -18,20 +18,21 @@
  */
 package org.apache.felix.ipojo.architecture;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Dictionary;
+import java.util.Properties;
 
 import org.apache.felix.ipojo.ComponentFactory;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 
 /**
  * Component Type description.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ComponentDescription {
+public class ComponentTypeDescription {
 
     /**
      * Provided service by the component type.
@@ -42,13 +43,6 @@
      * Configuration Properties accepted by the component type.
      */
     private PropertyDescription[] m_properties = new PropertyDescription[0];
-    
-    /**
-     * List of required properties.
-     * This list contains only property which does not have a default value.
-     */
-    private List m_requiredProperties = new ArrayList();
-
 
     /**
      * Represented factory.
@@ -59,13 +53,9 @@
      * Constructor.
      * @param factory : represented factory.
      */
-    public ComponentDescription(Factory factory) {
+    public ComponentTypeDescription(Factory factory) {
         m_factory = factory;
     }
-    
-    public List getRequiredProperties() {
-        return m_requiredProperties;
-    }
 
     /**
      * Get a printable form of the current component type description.
@@ -98,36 +88,40 @@
      * @param value : property value.
      */
     public void addProperty(String name, String value) {
-        PropertyDescription pd = new PropertyDescription(name, String.class.getName(), value);
-        addProperty(pd);
+        addProperty(name, value, false);
+    }
+    
+    /**
+     * Add a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     * @param immutable : the property is immutable.
+     */
+    public void addProperty(String name, String value, boolean immutable) {
+        PropertyDescription prop = new PropertyDescription(name, String.class.getName(), value);
+        addProperty(prop);
     }
 
     /**
      * Add a configuration properties to the component type.
      * @param pd : the property to add
      */
-    public void addProperty(PropertyDescription pd) {
-        String n = pd.getName();
-        if ("name".equals(n)) {
-            pd = new PropertyDescription(n, pd.getType(), null); // Instance name case.
-        }
+    public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
+        String name = pd.getName();
+        if ("name".equals(name)) {
+            pd = new PropertyDescription(name, pd.getType(), null); //NOPMD Instance name case.
+        } 
         
         // Check if the property is not already in the array
         for (int i = 0; i < m_properties.length; i++) {
             PropertyDescription desc = m_properties[i];
-            if (desc.getName().equals(n)) {
-                return;
-            }
+            if (desc.getName().equals(name)) { return; }
         }
 
         PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
         System.arraycopy(m_properties, 0, newProps, 0, m_properties.length);
         newProps[m_properties.length] = pd;
         m_properties = newProps;
-        
-        if (pd.getValue() == null) {
-            m_requiredProperties.add(n);
-        }
     }
 
     /**
@@ -156,6 +150,37 @@
     public String getName() {
         return m_factory.getName();
     }
+    
+    /**
+     * Compute the default service properties to publish : 
+     * factory.name, service.pid, component.providedServiceSpecification, component.properties, component.description, factory.State.
+     * @return : the dictionary of properties to publish.
+     */
+    public Dictionary getPropertiesToPublish() {
+        Properties props = new Properties();
+
+        props.put("factory.name", m_factory.getName());
+        props.put(Constants.SERVICE_PID, m_factory.getName()); // Service PID is required for the integration in the configuration admin.
+
+        props.put("component.providedServiceSpecifications", m_providedServiceSpecification);
+        props.put("component.properties", m_properties);
+        props.put("component.description", this);
+        
+        // add every immutable property
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].isImmutable() && m_properties[i].getValue() != null) {
+                props.put(m_properties[i].getName(), m_properties[i].getObjectValue(m_factory.getBundleContext()));
+            }
+        }
+
+        // Add factory state
+        props.put("factory.state", new Integer(m_factory.getState()));
+
+        return props;
+
+    }
+    
+    
 
     /**
      * Get the component type description.
@@ -165,14 +190,9 @@
         Element desc = new Element("Factory", "");
 
         desc.addAttribute(new Attribute("name", m_factory.getName()));
-        desc.addAttribute(new Attribute("bundle", "" + ((ComponentFactory) m_factory).getBundleContext().getBundle().getBundleId()));
-
-        String cn = getClassName();
-        if (cn == null) {
-            desc.addAttribute(new Attribute("Composite", "true"));
-        } else {
-            desc.addAttribute(new Attribute("Implementation-Class", getClassName()));
-        }
+        desc.addAttribute(
+                          new Attribute("bundle", 
+                                          Long.toString(((ComponentFactory) m_factory).getBundleContext().getBundle().getBundleId())));
 
         String state = "valid";
         if (m_factory.getState() == Factory.INVALID) {
@@ -181,12 +201,12 @@
         desc.addAttribute(new Attribute("state", state));
 
         // Display required & missing handlers
-        Element rh = new Element("RequiredHandlers", "");
-        rh.addAttribute(new Attribute("list", m_factory.getRequiredHandlers().toString()));
-        Element mh = new Element("MissingHandlers", "");
-        mh.addAttribute(new Attribute("list", m_factory.getMissingHandlers().toString()));
-        desc.addElement(rh);
-        desc.addElement(mh);
+        Element req = new Element("RequiredHandlers", "");
+        req.addAttribute(new Attribute("list", m_factory.getRequiredHandlers().toString()));
+        Element missing = new Element("MissingHandlers", "");
+        missing.addAttribute(new Attribute("list", m_factory.getMissingHandlers().toString()));
+        desc.addElement(req);
+        desc.addElement(missing);
 
         for (int i = 0; i < m_providedServiceSpecification.length; i++) {
             Element prov = new Element("provides", "");
@@ -198,10 +218,10 @@
             Element prop = new Element("property", "");
             prop.addAttribute(new Attribute("name", m_properties[i].getName()));
             prop.addAttribute(new Attribute("type", m_properties[i].getType()));
-            if (m_properties[i].getValue() != null) {
-                prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
-            } else {
+            if (m_properties[i].getValue() == null) {
                 prop.addAttribute(new Attribute("value", "REQUIRED"));
+            } else {
+                prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
             }
             desc.addElement(prop);
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
index 8847575..2cd3a5a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.ipojo.architecture;
 
-import org.apache.felix.ipojo.CompositeHandler;
 import org.apache.felix.ipojo.Handler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
@@ -43,21 +42,11 @@
     /**
      * Constructor.
      * 
-     * @param h : handler.
+     * @param handler : handler.
      */
-    public HandlerDescription(Handler h) {
-        m_handlerName = h.getClass().getName();
-        m_isValid = h.isValid();
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler.
-     */
-    public HandlerDescription(CompositeHandler h) {
-        m_handlerName = h.getClass().getName();
-        m_isValid = h.isValid();
+    public HandlerDescription(Handler handler) {
+        m_handlerName = handler.getClass().getName();
+        m_isValid = handler.isValid();
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
index 14bb1e8..3ebb43a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
@@ -57,7 +57,7 @@
     /**
      * Component Type of the instance.
      */
-    private ComponentDescription m_type;
+    private ComponentTypeDescription m_type;
 
     /**
      * COntained instance list.
@@ -70,16 +70,16 @@
      * @param name : the name of the component instance.
      * @param state : the state of the instance.
      * @param bundleId : bundle id owning this instance.
-     * @param cd : the component type description of this instance.
+     * @param desc : the component type description of this instance.
      */
-    public InstanceDescription(String name, int state, long bundleId, ComponentDescription cd) {
+    public InstanceDescription(String name, int state, long bundleId, ComponentTypeDescription desc) {
         m_name = name;
         m_state = state;
         m_createdObjects = new String[0];
         m_handlers = new HandlerDescription[0];
         m_containedInstances = new InstanceDescription[0];
         m_bundleId = bundleId;
-        m_type = cd;
+        m_type = desc;
     }
 
     /**
@@ -110,7 +110,7 @@
      * Get the component type description of the described instance.
      * @return : the component type description of this instance.
      */
-    public ComponentDescription getComponentDescription() {
+    public ComponentTypeDescription getComponentDescription() {
         return m_type;
     }
 
@@ -124,12 +124,12 @@
 
     /**
      * Add an handler description to the list.
-     * @param hd : the handler description to add
+     * @param desc : the handler description to add
      */
-    public void addHandler(HandlerDescription hd) {
+    public void addHandler(HandlerDescription desc) {
         // Verify that the dependency description is not already in the array.
         for (int i = 0; i < m_handlers.length; i++) {
-            if (m_handlers[i] == hd) {
+            if (m_handlers[i] == desc) {
                 return; // NOTHING TO DO, the description is already in the
                         // array
             }
@@ -137,7 +137,7 @@
         // The component Description is not in the array, add it
         HandlerDescription[] newHd = new HandlerDescription[m_handlers.length + 1];
         System.arraycopy(m_handlers, 0, newHd, 0, m_handlers.length);
-        newHd[m_handlers.length] = hd;
+        newHd[m_handlers.length] = desc;
         m_handlers = newHd;
     }
 
@@ -163,10 +163,10 @@
     /**
      * Set the state of the component.
      * 
-     * @param i : the state
+     * @param state : the state
      */
-    public void setState(int i) {
-        m_state = i;
+    public void setState(int state) {
+        m_state = state;
     }
 
     /**
@@ -215,7 +215,7 @@
             instance.addAttribute(new Attribute("state", "disposed"));
         }
         // Bundle
-        instance.addAttribute(new Attribute("bundle", "" + m_bundleId));
+        instance.addAttribute(new Attribute("bundle", Long.toString(m_bundleId)));
 
         // Component Type
         instance.addAttribute(new Attribute("component.type", m_type.getName()));
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
index f3f63f4..222be42 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
@@ -18,6 +18,10 @@
  */
 package org.apache.felix.ipojo.architecture;
 
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.BundleContext;
+
 /**
  * Property Information.
  * 
@@ -39,6 +43,14 @@
      * Default value of the property.
      */
     private String m_value = null;
+    
+    
+    /**
+     * Immutable property flag
+     * IF true, the property cannot be override by the instance configuration.
+     * Moreover, immutable properties are exposed on the factory service too.
+     */
+    private boolean m_immutable = false;
 
     /**
      * Constructor.
@@ -52,6 +64,21 @@
         m_type = type;
         m_value = value;
     }
+    
+    /**
+     * Constructor.
+     * 
+     * @param name : name of the property
+     * @param type : type of the property
+     * @param value : default value of the property
+     * @param immutable : the property is immutable.
+     */
+    public PropertyDescription(String name, String type, String value, boolean immutable) {
+        m_name = name;
+        m_type = type;
+        m_value = value;
+        m_immutable = immutable;
+    }
 
     /**
      * Get the current property name.
@@ -76,5 +103,27 @@
     public String getValue() {
         return m_value;
     }
+    
+    /**
+     * Is the property immutable.
+     * @return true if the property is immutable.
+     */
+    public boolean isImmutable() {
+        return m_immutable;
+    }
+    /**
+     * Get the object value of the current immutable property.
+     * @param context : bundle context to use to load classes.
+     * @return the object value of the current property.
+     */
+    public Object getObjectValue(BundleContext context) {
+        Class type = null;
+        try {
+            type = Property.computeType(m_type, context);
+            return Property.create(type, m_value);
+        } catch (ConfigurationException e) {
+            return m_value; // Cannot create the object.
+        }
+    }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
deleted file mode 100644
index 9994698..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.importer;
-
-import java.util.List;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Description of the Import Export Handler.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ExportDescription extends HandlerDescription {
-
-    /**
-     * List of exports.
-     */
-    private List m_exports;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler
-     * @param exporters : list of managed exports
-     */
-    public ExportDescription(CompositeHandler h, List exporters) {
-        super(h);
-        m_exports = exporters;
-    }
-
-    /**
-     * Build the ImportExport handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element handler = super.getHandlerInfo();
-        for (int i = 0; i < m_exports.size(); i++) {
-            ServiceExporter exp = (ServiceExporter) m_exports.get(i);
-            Element expo = new Element("Exports", "");
-            expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
-            expo.addAttribute(new Attribute("Filter", exp.getFilter()));
-            if (exp.isSatisfied()) {
-                expo.addAttribute(new Attribute("State", "resolved"));
-            } else {
-                expo.addAttribute(new Attribute("State", "unresolved"));
-            }
-            handler.addElement(expo);
-        }
-        return handler;
-
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
deleted file mode 100644
index 707dac8..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.ipojo.composite.service.importer;

-

-import java.util.ArrayList;

-import java.util.Dictionary;

-import java.util.List;

-

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

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

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

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

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

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

-import org.osgi.framework.BundleContext;

-

-/**

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

- * to the parent context.

- * 

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

- */

-public class ExportHandler extends CompositeHandler {

-

-    /**

-     * Service Scope.

-     */

-    private ServiceContext m_scope;

-

-    /**

-     * Parent context.

-     */

-    private BundleContext m_context;

-

-    /**

-     * List of exporters.

-     */

-    private List m_exporters = new ArrayList();

-

-    /**

-     * Is the handler valid ?

-     * (Lifecycle controller)

-     */

-    private boolean m_valid;

-

-    /**

-     * Initialize the component type.

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

-     * @param metadata : component type metadata.

-     * @throws ConfigurationException : occurs when the 'specification' attribute is missing

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

-     */

-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {

-        // Update the component type description

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

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

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

-            if (spec != null) { 

-                cd.addProvidedServiceSpecification(spec);

-            } else {

-                // Malformed exports

-                throw new ConfigurationException("Malformed exports - Missing the specification attribute");

-            }

-        }

-    }

-

-    /**

-     * Configure the handler.

-     * @param metadata : the metadata of the component

-     * @param conf : the instance configuration

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

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

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

-     */

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

-        m_context = getCompositeManager().getContext();

-        m_scope = getCompositeManager().getServiceContext();

-

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

-

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

-            boolean optional = false;

-            boolean aggregate = false;

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

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

-                

-            String opt = exp[i].getAttribute("optional");

-            optional =  opt != null && opt.equalsIgnoreCase("true");

-                

-            String agg = exp[i].getAttribute("aggregate");

-            aggregate = agg != null && agg.equalsIgnoreCase("true");

-

-            String f = exp[i].getAttribute("filter");

-            if (f != null) {

-                filter = "(&" + filter + f + ")";

-            }

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

-            m_exporters.add(si);

-        }

-    }

-

-    /**

-     * Start the handler.

-     * Start importers and exporters.

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

-     */

-    public void start() {

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

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

-            se.start();

-        }

-

-        isHandlerValid();

-

-    }

-

-    /**

-     * Stop the handler.

-     * Stop all importers and exporters.

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

-     */

-    public void stop() {

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

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

-            se.stop();

-        }

-    }

-

-    /**

-     * Check the handler validity.

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

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

-     */

-    private boolean isHandlerValid() {

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

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

-            if (!se.isSatisfied()) {

-                m_valid = false;

-                return false;

-            }

-        }

-

-        m_valid = true;

-        return true;

-    }

-

-    /**

-     * Notify the handler that an exporter becomes invalid.

-     * 

-     * @param exporter : the implicated exporter.

-     */

-    protected void invalidating(ServiceExporter exporter) {

-        // An export is no more valid

-        if (m_valid) {

-            m_valid = false;

-        }

-

-    }

-

-    /**

-     * Notify the handler that an exporter becomes valid.

-     * 

-     * @param exporter : the implicated exporter.

-     */

-    protected void validating(ServiceExporter exporter) {

-        // An import becomes valid

-        if (!m_valid) {

-            isHandlerValid();

-        }

-    }

-

-    /**

-     * Get the import / export handler description.

-     * @return the handler description

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

-     */

-    public HandlerDescription getDescription() {

-        return new ExportDescription(this, m_exporters);

-    }

-}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
deleted file mode 100644
index 0a56014..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.ipojo.composite.service.importer;

-

-import java.util.List;

-

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

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

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

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

-

-/**

- * Description of the Import Export Handler.

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

- */

-public class ImportDescription extends HandlerDescription {

-

-    /**

-     * List of exports.

-     */

-    private List m_imports;

-

-    /**

-     * Constructor.

-     * 

-     * @param h : composite handler

-     * @param importers : list of managed imports

-     */

-    public ImportDescription(CompositeHandler h, List importers) {

-        super(h);

-        m_imports = importers;

-    }

-

-    /**

-     * Build the ImportExport handler description.

-     * @return the handler description

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

-     */

-    public Element getHandlerInfo() {

-        Element handler = super.getHandlerInfo();

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

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

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

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

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

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

-            }

-            if (imp.isSatisfied()) {

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

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

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

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

-                    impo.addElement(pr);

-                }

-            } else {

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

-            }

-            handler.addElement(impo);

-        }

-        return handler;

-    }

-

-}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
deleted file mode 100644
index b54397f..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.importer;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-
-/**
- * This handler manages the import and the export of services from /
- * to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ImportHandler extends CompositeHandler {
-
-    /**
-     * Service Scope.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * Parent context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * List of importers.
-     */
-    private List m_importers = new ArrayList();
-
-    /**
-     * Is the handler valid ?
-     * (Lifecycle controller)
-     */
-    private boolean m_valid;
-    
-
-    /**
-     * Configure the handler.
-     * 
-     * @param metadata : the metadata of the component
-     * @param conf : the instance configuration
-     * @throws ConfigurationException : the specification attribute is missing. 
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
-        m_context = getCompositeManager().getContext();
-        m_scope = getCompositeManager().getServiceContext();
-        Element[] imp = metadata.getElements("requires");
-        
-        // Get instance filters
-        Dictionary filtersConfiguration = null;
-        if (conf.get("requires.filters") != null) {
-            filtersConfiguration = (Dictionary) conf.get("requires.filters");
-        }
-
-        for (int i = 0; i < imp.length; i++) {
-            boolean optional = false;
-            boolean aggregate = false;
-            String specification = imp[i].getAttribute("specification");
-
-            if (specification != null) {                
-                String opt = imp[i].getAttribute("optional");
-                optional = opt != null && opt.equalsIgnoreCase("true");
-
-                String agg = imp[i].getAttribute("aggregate");
-                aggregate = agg != null && agg.equalsIgnoreCase("true");
-
-                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
-                String f = imp[i].getAttribute("filter");
-                if (f != null) {
-                    filter = "(&" + filter + f + ")";
-                }
-                
-                String id = imp[i].getAttribute("id");
-                
-                int scopePolicy = -1;
-                String scope = imp[i].getAttribute("scope");
-                if (scope != null) {
-                    if (scope.equalsIgnoreCase("global")) {
-                        scopePolicy = PolicyServiceContext.GLOBAL;
-                    } else if (scope.equalsIgnoreCase("composite")) {
-                        scopePolicy = PolicyServiceContext.LOCAL;
-                    } else if (scope.equalsIgnoreCase("composite+global")) {
-                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
-                    }                
-                }
-                
-                // Configure instance filter if available
-                if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                    filter = (String) filtersConfiguration.get(id);
-                }
-                
-                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
-                m_importers.add(si);
-            } else { // Malformed import
-                log(Logger.ERROR, "Malformed imports : the specification attribute is mandatory");
-                throw new ConfigurationException("Malformed imports : the specification attribute is mandatory");
-            }
-        }
-    }
-
-    /**
-     * Start the handler.
-     * Start importers and exporters.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            si.start();
-        }
-        isHandlerValid();
-    }
-
-    /**
-     * Stop the handler.
-     * Stop all importers and exporters.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            si.stop();
-        }
-    }
-
-    /**
-     * Check the handler validity.
-     * @return true if all importers and exporters are valid
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    public boolean isHandlerValid() {
-        for (int i = 0; i < m_importers.size(); i++) {
-            ServiceImporter si = (ServiceImporter) m_importers.get(i);
-            if (!si.isSatisfied()) {
-                m_valid = false;
-                return false;
-            }
-        }
-        m_valid = true;
-        return true;
-    }
-
-    /**
-     * Notify the handler that an importer is no more valid.
-     * 
-     * @param importer : the implicated importer.
-     */
-    protected void invalidating(ServiceImporter importer) {
-        // An import is no more valid
-        if (m_valid) {
-            m_valid = false;
-        }
-    }
-
-    /**
-     * Notify the handler that an importer becomes valid.
-     * 
-     * @param importer : the implicated importer.
-     */
-    protected void validating(ServiceImporter importer) {
-        // An import becomes valid
-        if (!m_valid) {
-            isHandlerValid();
-        }
-    }
-
-    /**
-     * Get the import / export handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        return new ImportDescription(this, m_importers);
-    }
-    
-    public List getRequirements() {
-        return m_importers;
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
deleted file mode 100644
index 52347c5..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.importer;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Export an service from the scope to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceExporter implements TrackerCustomizer {
-
-    /**
-     * Destination context.
-     */
-    private BundleContext m_destination;
-
-    /**
-     * Origin context.
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Exported specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering internal provider.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should be exported several providers.
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is this exports optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Reference of the handler.
-     */
-    private ExportHandler m_handler;
-
-    /**
-     * Is the exporter valid?
-     */
-    private boolean m_isValid;
-    
-    /**
-     * Tracker tracking internal service (to export).
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Structure Reference, Registration, Service Object.
-     */
-    private class Record {
-        /**
-         * Internal Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * External Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Exposed object.
-         */
-        private Object m_svcObject;
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : exported service specification.
-     * @param filter : LDAP filter
-     * @param multiple : is the export an aggregate export?
-     * @param optional : is the export optional?
-     * @param from : internal service context
-     * @param to : external bundle context
-     * @param exp : handler
-     */
-    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to,
-            ExportHandler exp) {
-        this.m_destination = to;
-        this.m_origin = from;
-        this.m_handler = exp;
-        try {
-            this.m_filter = to.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-    }
-
-    /**
-     * Start method.
-     * Start the provider tracking and the publication.
-     */
-    public void start() {
-        m_tracker = new Tracker(m_origin, m_filter, this);
-        m_tracker.open();
-
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Transform service reference property in a dictionary.
-     * instance.name and factory.name are injected too.
-     * @param ref : the service reference.
-     * @return the dictionary containing all property of the given service reference.
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-
-        prop.put("instance.name", m_handler.getCompositeManager().getInstanceName());
-        prop.put("factory.name", m_handler.getCompositeManager().getFactory().getName());
-
-        return prop;
-    }
-
-    /**
-     * Stop an exporter.
-     * Remove the service listener
-     * Unregister all exported services.
-     */
-    public void stop() {
-        m_tracker.close();
-
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            rec.m_svcObject = null;
-            if (rec.m_reg != null) {
-                rec.m_reg.unregister();
-                rec.m_reg = null;
-                m_tracker.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
-        }
-
-        m_tracker = null;
-        m_records.clear();
-
-    }
-
-    /**
-     * Check the exporter validity.
-     * @return true if optional or 'valid'
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Get the list of records using the given reference.
-     * @param ref : the service reference
-     * @return the list of records using the given reference, empty if no record used this reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        return l;
-    }
-    
-    protected String getSpecification() {
-        return m_specification;
-    }
-    
-    public String getFilter() {
-        return m_filterStr;
-    }
-
-    /**
-     * An exported service appears.
-     * @param reference : service reference
-     * @return true as the filter guaranty the export.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference reference) {
-        return true;
-    }
-    
-    /**
-     * A service has been added in the tracker. Can now thest the validity of the exporter.
-     * @param reference : the new reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        Record rec = new Record();
-        rec.m_ref = reference;
-        m_records.add(rec);
-        // Publishing ?
-        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
-            rec.m_svcObject = m_tracker.getService(rec.m_ref);
-            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-        }
-        // Compute the new state
-        if (!m_isValid && isSatisfied()) {
-            m_isValid = true;
-            m_handler.validating(this);
-        }
-    }
-
-    /**
-     * An exported service was modified.
-     * @param reference : modified reference
-     * @param service : service object
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) { 
-        // A published service has been modified
-        List l = getRecordsByRef(reference);
-        for (int i = 0; i < l.size(); i++) { // Update the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_reg.setProperties(getProps(reference));
-            }
-        }
-    }
-    
-    /**
-     * An exported service disappears.
-     * @param reference : service reference
-     * @param service : service object
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-        List l = getRecordsByRef(reference);
-        for (int i = 0; i < l.size(); i++) { // Stop the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_svcObject = null;
-                rec.m_reg.unregister();
-                rec.m_reg = null;
-                m_tracker.ungetService(rec.m_ref);
-            }
-        }
-        m_records.removeAll(l);
-
-        // Check the validity & if we need to re-import the service
-        if (m_records.size() > 0) {
-            // There is other available services
-            if (!m_aggregate) { // Import the next one
-                Record rec = (Record) m_records.get(0);
-                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        } else {
-            if (!m_optional) {
-                m_isValid = false;
-                m_handler.invalidating(this);
-            }
-        }
-        
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
deleted file mode 100644
index 9118fd2..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.importer;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Import a service form the parent to the internal service registry.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceImporter implements TrackerCustomizer {
-
-    /**
-     * Destination context.
-     */
-    private ServiceContext m_destination;
-
-    /**
-     * Context where service need to be found. 
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Imported Specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering external providers.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should we importer several providers?
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is the import optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Is the importer valid?
-     */
-    private boolean m_isValid;
-    
-    /**
-     * Resolving policy.
-     */
-    private int m_policy;
-    
-    /**
-     * TRacker tracking imported service.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Reference on the handler.
-     */
-    private ImportHandler m_handler;
-
-    private class Record {
-        /**
-         * External Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * Internal Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Exposed Object.
-         */
-        private Object m_svcObject;
-        
-        /**
-         * Test object equality.
-         * @param o : object to confront against the current object.
-         * @return true if the two objects are equals (same service reference).
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        public boolean equals(Object o) {
-            if (o instanceof Record) {
-                Record rec = (Record) o;
-                return rec.m_ref == m_ref;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Requirement Id.
-     */
-    private String m_id;
-
-    /**
-     * Is this requirement attached to a service-level requirement.
-     */
-    private boolean m_isServiceLevelRequirement;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : targeted specification
-     * @param filter : LDAP filter
-     * @param multiple : should the importer imports several services ?
-     * @param optional : is the import optional ?
-     * @param from : parent context
-     * @param to : internal context
-     * @param policy : resolving policy
-     * @param id : requirement id (may be null)
-     * @param in : handler
-     */
-    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
-            ImportHandler in) {
-        this.m_destination = to;
-        try {
-            this.m_filter = from.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-        this.m_handler = in;
-        
-        if (m_id == null) {
-            m_id = m_specification;
-        } else {
-            m_id = id;
-        }
-        
-        if (policy == -1) {
-            m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL;  
-        } else {
-            m_policy = policy;
-        }
-    }
-
-    /**
-     * Start method to begin the import.
-     */
-    public void start() {
-        m_origin = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), m_policy);
-        m_tracker = new Tracker(m_origin, m_filter, this);
-        m_tracker.open();
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Get the properties for the exposed service from the given reference.
-     * 
-     * @param ref : the reference.
-     * @return the property dictionary
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-        return prop;
-    }
-
-    /**
-     * Stop the management of the import.
-     */
-    public void stop() {
-
-        m_tracker.close();
-
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            rec.m_svcObject = null;
-            if (rec.m_reg != null) {
-                rec.m_reg.unregister();
-                m_tracker.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
-        }
-        
-        m_tracker = null;
-        m_records.clear();
-
-    }
-
-    /**
-     * Check if the import is satisfied.
-     * @return true if the import is optional or at least one provider is imported
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Get the record list using the given reference.
-     * 
-     * @param ref : the reference
-     * @return the list containing all record using the given reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        return l;
-    }
-
-    public String getSpecification() {
-        return m_specification;
-    }
-
-    /**
-     * Build the list of imported service provider.
-     * @return the list of all imported services.
-     */
-    protected List getProviders() {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            l.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
-        }
-        return l;
-
-    }
-
-    public String getFilter() {
-        return m_filterStr;
-    }
-    
-    /**
-     * Set that this dependency is a service level dependency.
-     * This forces the scoping policy to be STRICT. 
-     * @param b
-     */
-    public void setServiceLevelDependency() {
-        m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
-    }
-
-    public String getId() {
-        return m_id;
-    }
-    
-    public boolean isServiceLevelRequirement() {
-        return m_isServiceLevelRequirement;
-    }
-    
-    public boolean isAggregate() {
-        return m_aggregate;
-    }
-    
-    public boolean isOptional() {
-        return m_optional;
-    }
-
-    /**
-     * A new service is detected.
-     * @param reference : service reference
-     * @return true if not already imported.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference reference) {
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == reference) {
-                return false; // Already contained
-            }
-        }
-        return true;
-    }
-    
-    /**
-     * The given service reference was added inside the tracker list.
-     * Register the internal service.
-     * @param reference : added reference
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        Record rec = new Record();
-        rec.m_ref = reference;
-        m_records.add(rec);
-        // Publishing ?
-        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
-            rec.m_svcObject = m_tracker.getService(rec.m_ref);
-            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-        }
-        // Compute the new state
-        if (!m_isValid && isSatisfied()) {
-            m_isValid = true;
-            m_handler.validating(this);
-        }
-    }
-
-    /**
-     * An imported service was modified.
-     * @param reference : service reference
-     * @param service : service object (if already get)
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) {
-        List l = getRecordsByRef(reference);
-        for (int i = 0; i < l.size(); i++) { // Stop the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_reg.setProperties(getProps(rec.m_ref));
-            }
-        }
-    }
-
-    /**
-     * An imported service disappears.
-     *@param reference : service reference
-     * @param service : service object (if already get)
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-        List l = getRecordsByRef(reference);
-        for (int i = 0; i < l.size(); i++) { // Stop the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_svcObject = null;
-                rec.m_reg.unregister();
-                rec.m_reg = null;
-                m_tracker.ungetService(rec.m_ref);
-            }
-        }
-        m_records.removeAll(l);
-
-        // Check the validity & if we need to re-import the service
-        if (m_records.size() > 0) {
-            // There is other available services
-            if (!m_aggregate) { // Import the next one
-                Record rec = (Record) m_records.get(0);
-                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
-                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        } else {
-            if (!m_optional) {
-                m_isValid = false;
-                m_handler.invalidating(this);
-            }
-        }
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
deleted file mode 100644
index c3275b9..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.instantiator;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Description of the Service Creator Handler.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceInstantiatorDescription extends HandlerDescription {
-
-    /**
-     * List of managed service instances.
-     */
-    private List m_instances;
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler
-     * @param insts : list of service instance
-     */
-    public ServiceInstantiatorDescription(CompositeHandler h, List insts) {
-        super(h);
-        m_instances = insts;
-    }
-
-    /**
-     * Build service instantiator handler description.
-     * @return the handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element services = super.getHandlerInfo();
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            Element service = new Element("Service", "");
-            service.addAttribute(new Attribute("Specification", inst.getSpecification()));
-            String state = "unresolved";
-            if (inst.isSatisfied()) {
-                state = "resolved";
-            }
-            service.addAttribute(new Attribute("State", state));
-            Map map = inst.getUsedReferences();
-            Set keys = map.keySet();
-            Iterator it = keys.iterator();
-            while (it.hasNext()) {
-                ServiceReference ref = (ServiceReference) it.next();
-                Object o = map.get(ref);
-                if (o != null) {
-                    Element fact = new Element("Factory", "");
-                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) o).getFactory().getName()));
-                    service.addElement(fact);
-                }
-            }
-            services.addElement(service);
-        }
-        return services;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
deleted file mode 100644
index b0f1bac..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.instantiator;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Service Instantiator Class. This handler allows to instantiate service
- * instance inside the composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceInstantiatorHandler extends CompositeHandler {
-
-    /**
-     * Is the handler valid ?
-     * (Lifecycle controller)
-     */
-    private boolean m_isValid;
-
-    /**
-     * List of instances to manage.
-     */
-    private List/* <SvcInstance> */m_instances = new ArrayList();
-
-    /**
-     * Configure the handler.
-     * 
-     * @param metadata : the metadata of the component
-     * @param conf : the instance configuration
-     * @throws ConfigurationException : the specification attribute is missing
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
-        Element[] services = metadata.getElements("service");
-        for (int i = 0; i < services.length; i++) {
-            String spec = services[i].getAttribute("specification");
-            if (spec == null) {
-                throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
-            }
-            String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
-            String f = services[i].getAttribute("filter");
-            if (f != null) {
-                filter = "(&" + filter + f + ")";
-            }
-            Properties prop = new Properties();
-            for (int k = 0; k < services[i].getElements("property").length; k++) {
-                String key = services[i].getElements("property")[k].getAttribute("name");
-                String value = services[i].getElements("property")[k].getAttribute("value");
-                prop.put(key, value);
-            }
-            String ag = services[i].getAttribute("aggregate");
-            boolean agg = ag != null && ag.equalsIgnoreCase("true");
-            
-            String op = services[i].getAttribute("optional");
-            boolean opt = op != null && op.equalsIgnoreCase("true");
-            
-            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
-            m_instances.add(inst);
-        }
-    }
-
-    /**
-     * Start the service instantiator handler.
-     * Start all created service instance.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() {
-        // Init
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            inst.start();
-        }
-
-        m_isValid = isHandlerValid();
-    }
-
-    /**
-     * Check the handler validity.
-     * @return true if all created service instances are valid
-     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
-     */
-    private boolean isHandlerValid() {
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            if (!inst.isSatisfied()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Handler stop method.
-     * Stop all created service instance.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_instances.size(); i++) {
-            SvcInstance inst = (SvcInstance) m_instances.get(i);
-            inst.stop();
-        }
-        m_instances.clear();
-    }
-
-    /**
-     * An service instance becomes valid.
-     */
-    public void validate() {
-        if (!m_isValid) {
-            if (isHandlerValid()) {
-                m_isValid = true;
-            }
-        }
-    }
-
-    /**
-     * A service instance becomes invalid.
-     */
-    public void invalidate() {
-        if (m_isValid) {
-            if (!isHandlerValid()) {
-                m_isValid = false;
-            }
-        }
-    }
-
-    /**
-     * Get the service instantiator handler description.
-     * @return the description
-     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
-     */
-    public HandlerDescription getDescription() {
-        return new ServiceInstantiatorDescription(this, m_instances);
-    }
-    
-    public List getInstances() {
-        return m_instances;
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
deleted file mode 100644
index a738675..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.instantiator;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.MissingHandlerException;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.UnacceptableConfiguration;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Manage a service instantiation. This service create component instance
- * providing the required service specification.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class SvcInstance implements TrackerCustomizer {
-
-    /**
-     * Required specification.
-     */
-    private String m_specification;
-
-    /**
-     * Configuration to push to the instance.
-     */
-    private Dictionary m_configuration;
-
-    /**
-     * Map of factory references => instance or NO_INSTANCE.
-     */
-    private Map /* ServiceReference */m_usedRef = new HashMap();
-
-    /**
-     * Does we instantiate several provider ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the service optional ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * Handler creating the service instance.
-     */
-    private ServiceInstantiatorHandler m_handler;
-
-    /**
-     * Service Context (internal scope).
-     */
-    private ServiceContext m_context;
-
-    /**
-     * True if the service instantiation is valid.
-     */
-    private boolean m_isValid = false;
-
-    /**
-     * Tracker used to track required factory.
-     */
-    private Tracker m_tracker;
-
-    /**
-     * Constructor.
-     * @param h : the handler.
-     * @param spec : required specification.
-     * @param conf : instance configuration.
-     * @param isAgg : is the service instance an aggregate service ?
-     * @param isOpt : is the service instance optional ?
-     * @param filt : LDAP filter
-     */
-    public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
-        m_handler = h;
-        m_context = h.getCompositeManager().getServiceContext();
-        m_specification = spec;
-        m_configuration = conf;
-        m_isAggregate = isAgg;
-        m_isOptional = isOpt;
-        try {
-            m_tracker  = new Tracker(m_context, h.getCompositeManager().getContext().createFilter(filt), this);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Start the service instance.
-     * @param sc
-     */
-    public void start() {
-        m_tracker.open();
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Stop the service instance.
-     */
-    public void stop() {
-        m_tracker.close();
-        
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        while (it.hasNext()) {
-            ServiceReference ref = (ServiceReference) it.next();
-            Object o = m_usedRef.get(ref);
-            if (o != null) {
-                ((ComponentInstance) o).dispose();
-            }
-        }
-        m_usedRef.clear();
-        m_tracker = null;
-        m_isValid = false;
-    }
-
-    /**
-     * Check if an instance is already created.
-     * @return true if at least one instance is created.
-     */
-    private boolean isAnInstanceCreated() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        while (it.hasNext()) {
-            if (m_usedRef.get(it.next()) != null)  {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Create an instance for the given reference.
-     * The instance is not added inside the map.
-     * @param factory : the factory from which we need to create the instance.
-     * @return the created component instance.
-     */
-    private ComponentInstance createInstance(Factory factory) {
-        // Add an unique name if not specified.
-        Properties p = new Properties();
-        Enumeration kk = m_configuration.keys();
-        while (kk.hasMoreElements()) {
-            String k = (String) kk.nextElement();
-            p.put(k, m_configuration.get(k));
-        }
-        ComponentInstance instance = null;
-        try {
-            instance = factory.createComponentInstance(p);
-        } catch (UnacceptableConfiguration e) {
-            e.printStackTrace();
-        } catch (MissingHandlerException e) {
-            e.printStackTrace();
-        } catch (ConfigurationException e) {
-            e.printStackTrace();
-        }
-        return instance;
-    }
-
-    /**
-     * Create an instance for the next available factory.
-     */
-    private void createNextInstance() {
-        Set keys = m_usedRef.keySet();
-        Iterator it = keys.iterator();
-        ServiceReference ref = (ServiceReference) it.next();
-        try {
-            Factory factory = (Factory) m_context.getService(ref);
-
-            // Add an unique name if not specified.
-            Properties p = new Properties();
-            Enumeration kk = m_configuration.keys();
-            while (kk.hasMoreElements()) {
-                String k = (String) kk.nextElement();
-                p.put(k, m_configuration.get(k));
-            }
-            
-            ComponentInstance instance = factory.createComponentInstance(p);
-            m_usedRef.put(ref, instance);
-            m_context.ungetService(ref);
-        } catch (UnacceptableConfiguration e) {
-            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        } catch (MissingHandlerException e) {
-            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        } catch (ConfigurationException e) {
-            m_handler.log(Logger.ERROR, "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
-        }
-    }
-
-
-
-    /**
-     * Check if the service instance is satisfied.
-     * @return true if the service instance if satisfied.
-     */
-    public boolean isSatisfied() {
-        return m_isOptional || m_usedRef.size() > 0;
-    }
-
-    /**
-     * Does the service instance match with the given factory ?
-     * @param fact : the factory to test.
-     * @return true if the factory match, false otherwise.
-     */
-    private boolean match(Factory fact) {
-        //TODO : use the service reference instead of the factory object to avoid to get the factory.
-        // Check if the factory can provide the specification
-        Element[] provides = fact.getDescription().getElements("provides");
-        for (int i = 0; i < provides.length; i++) {
-            if (provides[i].getAttribute("specification").equals(m_specification)) {
-
-                // Check that the factory needs every properties contained in
-                // the configuration
-                Enumeration e = m_configuration.keys();
-                while (e.hasMoreElements()) {
-                    String k = (String) e.nextElement();
-                    if (!containsProperty(k, fact)) {
-                        return false;
-                    }
-                }
-
-                // Add an unique name if not specified.
-                Properties p = new Properties();
-                Enumeration keys = m_configuration.keys();
-                while (keys.hasMoreElements()) {
-                    String k = (String) keys.nextElement();
-                    p.put(k, m_configuration.get(k));
-                }
-
-                // Check the acceptability.
-                return fact.isAcceptable(p);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Does the factory support the given property ?
-     * 
-     * @param name : name of the property
-     * @param factory : factory to test
-     * @return true if the factory support this property
-     */
-    private boolean containsProperty(String name, Factory factory) {
-        Element[] props = factory.getDescription().getElements("property");
-        for (int i = 0; i < props.length; i++) {
-            if (props[i].getAttribute("name").equalsIgnoreCase(name)) {
-                return true;
-            }
-        }
-        if (name.equalsIgnoreCase("name")) {
-            return true;
-        } // Skip the name property
-        return false;
-    }
-
-    /**
-     * Get the required specification.
-     * @return the required specification.
-     */
-    public String getSpecification() {
-        return m_specification;
-    }
-    
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-    
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-    /**
-     * Get the map of used references [reference, component instance].
-     * @return the map of used references.
-     */
-    protected Map getUsedReferences() {
-        return m_usedRef;
-    }
-
-    /**
-     * A factory potentially matching with the managed instance appears.
-     * @param reference : service reference
-     * @return : true if the factory match
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-     */
-    public boolean addingService(ServiceReference reference) {
-        Factory fact = (Factory) m_tracker.getService(reference);
-        if (match(fact)) {
-            m_tracker.ungetService(reference);
-            return true;
-        } else {
-            m_tracker.ungetService(reference);
-            return false;
-        }
-        
-    }
-    
-    /**
-     * A matching service reference has been added in the tracker. 
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
-     */
-    public void addedService(ServiceReference reference) {
-        Factory fact = (Factory) m_tracker.getService(reference);
-        if (m_isAggregate) { // Create an instance for the new factory
-            m_usedRef.put(reference, createInstance(fact));
-            if (!m_isValid) {
-                m_isValid = true;
-                m_handler.validate();
-            }
-        } else {
-            if (!isAnInstanceCreated()) {
-                m_usedRef.put(reference, createInstance(fact));
-            } else {
-                m_usedRef.put(reference, null); // Store the reference
-            }
-            if (!m_isValid) {
-                m_isValid = true;
-                m_handler.validate();
-            }
-        }
-        m_tracker.ungetService(reference);
-    }
-
-    /**
-     * A used factory was modified.
-     * @param reference : service reference
-     * @param service : object if already get
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void modifiedService(ServiceReference reference, Object service) { } 
-        
-    /**
-     * A used factory disappears.
-     * @param reference : service reference
-     * @param service : object if already get
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
-     */
-    public void removedService(ServiceReference reference, Object service) {
-     // Remove the reference is contained
-        Object o = m_usedRef.remove(reference);
-        if (o != null) {
-            ((ComponentInstance) o).dispose();
-            if (m_usedRef.size() > 0) {
-                if (!m_isAggregate) {
-                    createNextInstance(); // Create an instance with another factory
-                }
-            } else { // No more candidate
-                if (!m_isOptional) {
-                    m_isValid = false;
-                    m_handler.invalidate();
-                }
-            }
-        }
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
deleted file mode 100644
index 994f01e..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentFactory;
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeManager;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.MissingHandlerException;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.UnacceptableConfiguration;
-import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-
-/**
- * Composite Provided Service.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedService {
-
-    /**
-     * Composite Manager.
-     */
-    private CompositeManager m_manager;
-
-    /**
-     * Composition Model.
-     */
-    private CompositionMetadata m_composition;
-
-    /**
-     * generated POJO class.
-     */
-    private byte[] m_clazz;
-
-    /**
-     * Metadata of the POJO. 
-     */
-    private Element m_metadata;
-
-    /**
-     * Internal context.
-     */
-    private ServiceContext m_scope;
-
-    /**
-     * External context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * Created Factory.
-     */
-    private ComponentFactory m_factory;
-
-    /**
-     * Created Instance.
-     */
-    private ComponentInstance m_instance;
-
-    /**
-     * Exporter.
-     */
-    private ServiceExporter m_exports;
-    
-    /**
-     * Created instance name.
-     */
-    private String m_instanceName;
-
-    /**
-     * Constructor.
-     * The delegation mapping is infers in this method.
-     * @param handler : the handler.
-     * @param element : 'provides' element.
-     * @param name : name of this provided service.
-     */
-    public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {
-        m_manager = handler.getCompositeManager();
-        m_scope = m_manager.getServiceContext();
-        m_context = m_manager.getContext();
-        m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);
-    }
-
-    /**
-     * Start method.
-     * Build service implementation type, factory and instance.
-     * @throws CompositionException if a consistent mapping cannot be discovered.
-     */
-    public void start() throws CompositionException {
-        m_composition.buildMapping();
-        
-        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";
-        m_clazz = m_composition.buildPOJO();
-        m_metadata = m_composition.buildMetadata(m_instanceName);
-
-        // Create the factory
-        m_factory = new ComponentFactory(m_context, m_clazz, m_metadata);
-        m_factory.start();
-
-        // Create the exports
-        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(instance.name=" + m_instanceName + ")", false, false,
-                m_scope, m_context, this);
-        m_exports.start();
-    }
-
-    /**
-     * Stop the provided service.
-     * Kill the exporter, the instance and the factory.
-     */
-    public void stop() {
-        if (m_exports != null) {
-            m_exports.stop();
-            m_exports = null;
-        }
-        if (m_instance != null) {
-            m_instance.dispose();
-            m_instance = null;
-        }
-        if (m_factory != null) {
-            m_factory.stop();
-            m_factory = null;
-        }
-    }
-
-    protected CompositeManager getManager() {
-        return m_manager;
-    }
-
-    /**
-     * The exporter becomes valid.
-     * @param exporter : the exporter
-     */
-    public void validating(ServiceExporter exporter) {
-    }
-
-    /**
-     * The exporter becomes invalid.
-     * @param exporter : the exporter
-     */
-    public void invalidating(ServiceExporter exporter) {
-    }
-
-    /**
-     * Unregister published service.
-     */
-    protected void unregister() {
-        if (m_instance != null) {
-            m_instance.dispose();
-            m_instance = null;
-        }
-    }
-
-    /**
-     * Register published service.
-     */
-    protected void register() {
-        if (m_exports != null) {
-            if (m_instance != null) { m_instance.dispose(); }
-            Properties p = new Properties();
-            p.put("name", m_instanceName);
-            List fields = m_composition.getFieldList();
-            for (int i = 0; i < fields.size(); i++) {
-                FieldMetadata fm = (FieldMetadata) fields.get(i);
-                if (fm.isUseful() && !fm.getSpecification().isInterface()) {
-                    String type = fm.getSpecification().getComponentType();
-                    Object o = getObjectByType(type);
-                    p.put(fm.getName(), o); 
-                }
-            }
-            try {
-                m_instance = m_factory.createComponentInstance(p, m_manager.getServiceContext());
-            } catch (UnacceptableConfiguration e) {
-                e.printStackTrace();
-            } catch (MissingHandlerException e) {
-                e.printStackTrace();
-            } catch (ConfigurationException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Get an object from the given type.
-     * @param type : type
-     * @return an object from an instance of this type or null
-     */
-    private Object getObjectByType(String type) {
-        InstanceHandler h = (InstanceHandler) m_manager.getCompositeHandler("org.apache.felix.ipojo.composite.instance.InstanceHandler");
-        Object o = h.getObjectFromInstance(type);
-        if (o == null) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "An instance object cannot be found for the type : " + type);
-        }
-        return o;
-        
-    }
-
-    public String getSpecification() {
-        return m_composition.getSpecificationMetadata().getName();
-    }
-
-    /**
-     * Check the provided service state.
-     * @return true if the exporter is publishing.
-     */
-    public boolean getState() {
-        if (m_exports != null && m_exports.isPublishing()) {
-            return true;
-        }
-        return false;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
deleted file mode 100644
index ef86839..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.Factory;
-import org.apache.felix.ipojo.HandlerManager;
-import org.apache.felix.ipojo.IPojoConfiguration;
-import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.composite.instance.InstanceHandler;
-import org.apache.felix.ipojo.composite.service.importer.ImportHandler;
-import org.apache.felix.ipojo.composite.service.importer.ServiceImporter;
-import org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler;
-import org.apache.felix.ipojo.composite.service.instantiator.SvcInstance;
-import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ManifestMetadataParser;
-import org.apache.felix.ipojo.parser.ParseException;
-import org.apache.felix.ipojo.util.Logger;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Composite Provided Service Handler.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedServiceHandler extends CompositeHandler {
-
-    /**
-     * External context.
-     */
-    private BundleContext m_context;
-
-    /**
-     * List of "available" services in the internal context.
-     */
-    private List m_services = new ArrayList();
-
-    /**
-     * List of managed services.
-     */
-    private List m_managedServices = new ArrayList();
-
-    /**
-     * Handler validity.
-     * (Lifecycle controller)
-     */
-    private boolean m_valid = false;
-
-    /**
-     * List of component type.
-     */
-    private List m_types;
-
-    /**
-     * Initialize the component type.
-     * @param cd : component type description to populate.
-     * @param metadata : component type metadata.
-     * @throws ConfigurationException : metadata are incorrect.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
-     */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
-        Element[] provides = metadata.getElements("provides", "");
-        for (int i = 0; i < provides.length; i++) {
-            String spec = provides[i].getAttribute("specification");
-            if (spec != null) {
-                cd.addProvidedServiceSpecification(spec);
-            } else {
-                throw new ConfigurationException("Malformed provides : the specification attribute is mandatory");
-            }
-        }
-    }
-
-    /**
-     * Configure the handler.
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
-     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
-     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
-     */
-    public void configure(Element metadata, Dictionary configuration) {
-        m_context = getCompositeManager().getContext();
-
-        // Get composition metadata
-        Element[] provides = metadata.getElements("provides", "");
-        if (provides.length == 0) { return; }
-
-        for (int i = 0; i < provides.length; i++) {
-            ProvidedService ps = new ProvidedService(this, provides[i], "" + i);
-            m_managedServices.add(ps);
-        }
-    }
-
-    /**
-     * Start method.
-     * Start all managed provided service.
-     * @see org.apache.felix.ipojo.CompositeHandler#start()
-     */
-    public void start() {
-        // Compute imports and instances
-        computeAvailableServices();
-        computeAvailableTypes();
-        
-        for (int i = 0; i < m_managedServices.size(); i++) {
-            ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-            try {
-                checkServiceSpecification(ps);
-                ps.start();
-            } catch (CompositionException e) {
-                log(Logger.ERROR, "Cannot start the provided service handler", e);
-                if (m_valid) { m_valid = false; }
-                return;
-            }
-        }
-        m_valid = true;
-    }
-
-    /**
-     * Stop method.
-     * Stop all managed provided service.
-     * @see org.apache.felix.ipojo.CompositeHandler#stop()
-     */
-    public void stop() {
-        for (int i = 0; i < m_managedServices.size(); i++) {
-            ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-            ps.stop();
-        }
-    }
-
-    /**
-     * Handler state changed.
-     * @param state : the new instance state.
-     * @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        if (state == ComponentInstance.INVALID) {
-            for (int i = 0; i < m_managedServices.size(); i++) {
-                ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-                ps.unregister();
-            }
-            return;
-        }
-
-        // If the new state is VALID => register all the services
-        if (state == ComponentInstance.VALID) {
-            for (int i = 0; i < m_managedServices.size(); i++) {
-                ProvidedService ps = (ProvidedService) m_managedServices.get(i);
-                ps.register();
-            }
-            return;
-        }
-    }
-
-    /**
-     * Build the list of available specification.
-     * @return the list of available specification.
-     */
-    protected List getSpecifications() {
-        return m_services;
-    }
-
-    /**
-     * Build the list of available specifications.
-     */
-    private void computeAvailableServices() {
-        // Get instantiated services :
-        ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        ServiceInstantiatorHandler sh = (ServiceInstantiatorHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":service");
-
-        for (int i = 0; sh != null && i < sh.getInstances().size(); i++) {
-            SvcInstance svc = (SvcInstance) sh.getInstances().get(i);
-            String itf = svc.getSpecification();
-            boolean agg = svc.isAggregate();
-            boolean opt = svc.isOptional();
-
-            SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
-            m_services.add(sm);
-        }
-
-        for (int i = 0; ih != null && i < ih.getRequirements().size(); i++) {
-            ServiceImporter si = (ServiceImporter) ih.getRequirements().get(i);
-            String itf = si.getSpecification();
-            boolean agg = si.isAggregate();
-            boolean opt = si.isOptional();
-
-            SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
-            m_services.add(sm);
-        }
-    }
-
-    /**
-     * Check composite requirement against service specification requirement is available.
-     * @param ps : the provided service to check
-     * @throws CompositionException : occurs if the specification field of the service specification cannot be analyzed correctly.
-     */
-    private void checkServiceSpecification(ProvidedService ps) throws CompositionException {
-        try {
-            Class spec = m_context.getBundle().loadClass(ps.getSpecification());
-            Field specField = spec.getField("specification");
-            Object o = specField.get(null);
-            if (o instanceof String) {
-                Element specification = ManifestMetadataParser.parse((String) o);
-                Element[] reqs = specification.getElements("requires");
-                for (int j = 0; j < reqs.length; j++) {
-                    ServiceImporter imp = getAttachedRequirement(reqs[j]);
-                    if (imp != null) {
-                        // Fix service-level dependency flag
-                        imp.setServiceLevelDependency();
-                    }
-                    checkRequirement(imp, reqs[j]);
-                }
-            } else {
-                log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The specification field of the service specification " + ps.getSpecification() + " need to be a String");
-                throw new CompositionException("Service Specification checking failed : The specification field of the service specification " + ps.getSpecification() + " need to be a String");
-            }
-        } catch (NoSuchFieldException e) {
-            return; // No specification field
-        } catch (ClassNotFoundException e) {
-            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The service specification " + ps.getSpecification() + " cannot be load");
-            throw new CompositionException("The service specification " + ps.getSpecification() + " cannot be load : " + e.getMessage());
-        } catch (IllegalArgumentException e) {
-            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
-            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
-        } catch (IllegalAccessException e) {
-            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
-            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " is not accessible : " + e.getMessage());
-        } catch (ParseException e) {
-            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());
-            throw new CompositionException("The field 'specification' of the service specification " + ps.getSpecification() + " does not contain a valid String : " + e.getMessage());
-        }
-    }
-
-    /**
-     * Look for the implementation (i.e. composite) requirement for the given service-level requirement metadata.
-     * @param element : the service-level requirement metadata
-     * @return the ServiceImporter object, null if not found or if the DependencyHandler is not plugged to the instance
-     */
-    private ServiceImporter getAttachedRequirement(Element element) {
-        ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        if (ih == null) { return null; }
-
-        String id = element.getAttribute("id");
-        if (id != null) {
-            // Look for dependency Id
-            for (int i = 0; i < ih.getRequirements().size(); i++) {
-                ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
-                if (imp.getId().equals(id)) { return imp; }
-            }
-        }
-
-        // If not found or no id, look for a dependency with the same specification
-        String requirement = element.getAttribute("specification");
-        for (int i = 0; i < ih.getRequirements().size(); i++) {
-            ServiceImporter imp = (ServiceImporter) ih.getRequirements().get(i);
-            if (imp.getSpecification().equals(requirement)) { return imp; }
-        }
-        return null;
-    }
-
-    /**
-     * Check the correctness of the composite requirement against the service level dependency.
-     * @param imp : requirement to check
-     * @param elem : service-level dependency metadata
-     * @throws CompositionException : occurs if the requirement does not match with service-level specification requirement
-     */
-    private void checkRequirement(ServiceImporter imp, Element elem) throws CompositionException {
-        String op = elem.getAttribute("optional");
-        boolean opt = op != null && op.equalsIgnoreCase("true");
-
-        String ag = elem.getAttribute("aggregate");
-        boolean agg = ag != null && ag.equalsIgnoreCase("true");
-
-        if (imp == null) {
-            // Add the missing requirement
-            ImportHandler ih = (ImportHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-            if (ih == null) {
-                // Look for the import handler factory
-                HandlerManager ci = null;
-                try {
-                    ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(&(handler.name=requires)(handler.namespace=" + IPojoConfiguration.IPOJO_NAMESPACE + ")(handler.type=composite))");
-                    Factory factory = (Factory) m_context.getService(refs[0]);
-                    ci = (HandlerManager) factory.createComponentInstance(null, getCompositeManager().getServiceContext());
-                } catch (Exception e) {
-                    e.printStackTrace(); // Should not happen
-                }
-                // Add the required handler 
-                try {
-                    ci.init(getCompositeManager(), new Element("composite", ""), new Properties());
-                } catch (ConfigurationException e) {
-                    log(Logger.ERROR, "Internal error : cannot configure the Import Handler : " + e.getMessage());
-                    throw new CompositionException("Internal error : cannot configure the Import Handler : " + e.getMessage());
-                }
-                ih = (ImportHandler) ci.getHandler();
-                getCompositeManager().addCompositeHandler(ci);
-            }
-            String spec = elem.getAttribute("specification");
-            String filter = "(&(objectClass=" + spec + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
-            String f = elem.getAttribute("filter");
-            if (f != null) {
-                filter = "(&" + filter + f + ")";
-            }
-            
-            ServiceImporter si = new ServiceImporter(spec, filter, agg, opt, getCompositeManager().getContext(), getCompositeManager().getServiceContext(), PolicyServiceContext.LOCAL, null, ih);
-            ih.getRequirements().add(si);
-            SpecificationMetadata sm = new SpecificationMetadata(spec, m_context, agg, opt, this);
-            m_services.add(sm); // Update the available types
-            return;
-        }
-
-        if (imp.isAggregate() && !agg) {
-            log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
-            throw new CompositionException("The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
-        }
-
-        String filter = elem.getAttribute("filter");
-        if (filter != null) {
-            String filter2 = imp.getFilter();
-            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
-                log(Logger.ERROR, "[" + getCompositeManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
-                throw new CompositionException("The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
-            }
-        }
-    }
-
-    public HandlerDescription getDescription() {
-        return new ProvidedServiceHandlerDescription(this, m_managedServices);
-    }
-
-    /**
-     * Build available instance types.
-     */
-    private void computeAvailableTypes() {
-        InstanceHandler ih = (InstanceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":instance");
-        if (ih == null) {
-            m_types = new ArrayList();
-        } else {
-            m_types = ih.getUsedType();
-        }
-    }
-
-    public List getInstanceType() {
-        return m_types;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
deleted file mode 100644
index 19256d6..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.ipojo.CompositeHandler;
-import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.metadata.Attribute;
-import org.apache.felix.ipojo.metadata.Element;
-
-/**
- * Provided Service Handler Description for composite.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ProvidedServiceHandlerDescription extends HandlerDescription {
-
-    /**
-     * Provided Service Description list.
-     */
-    private List m_providedServices = new ArrayList();
-
-    /**
-     * Constructor.
-     * 
-     * @param h : composite handler.
-     * @param ps : The list of Provided Service.
-     */
-    public ProvidedServiceHandlerDescription(CompositeHandler h, List ps) {
-        super(h);
-        m_providedServices = ps;
-    }
-
-    /**
-     * Get the handler description.
-     * @return the provided service handler description
-     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
-     */
-    public Element getHandlerInfo() {
-        Element services = super.getHandlerInfo();
-        for (int i = 0; i < m_providedServices.size(); i++) {
-            ProvidedService ps = (ProvidedService) m_providedServices.get(i);
-            Element service = new Element("service", "");
-            String state = "unregistered";
-            if (ps.getState()) {
-                state = "registered";
-            }
-            String spec = "[" + ps.getSpecification() + "]";
-            service.addAttribute(new Attribute("Specification", spec));
-            service.addAttribute(new Attribute("State", state));
-            services.addElement(service);
-        }
-        return services;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
deleted file mode 100644
index 080c98d..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite.service.provides;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.ipojo.ServiceContext;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Export an service from the scope to the parent context.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceExporter implements ServiceListener {
-
-    /**
-     * Destination context.
-     */
-    private BundleContext m_destination;
-
-    /**
-     * Origin context.
-     */
-    private ServiceContext m_origin;
-
-    /**
-     * Exported specification.
-     */
-    private String m_specification;
-
-    /**
-     * LDAP filter filtering internal provider.
-     */
-    private Filter m_filter;
-
-    /**
-     * String form of the LDAP filter.
-     */
-    private String m_filterStr;
-
-    /**
-     * Should be exported several providers.
-     */
-    private boolean m_aggregate = false;
-
-    /**
-     * Is this exports optional?
-     */
-    private boolean m_optional = false;
-
-    /**
-     * Reference on the provided service.
-     */
-    private ProvidedService m_ps;
-
-    /**
-     * Is the export valid?
-     */
-    private boolean m_isValid;
-
-    private class Record {
-        /**
-         * Internal Reference.
-         */
-        private ServiceReference m_ref;
-        /**
-         * External Registration.
-         */
-        private ServiceRegistration m_reg;
-        /**
-         * Exposed object.
-         */
-        private Object m_svcObject;
-    }
-
-    /**
-     * List of managed records.
-     */
-    private List/* <Record> */m_records = new ArrayList()/* <Record> */;
-
-    /**
-     * Constructor.
-     * 
-     * @param specification : exported service specification.
-     * @param filter : LDAP filter
-     * @param multiple : is the export an aggregate export?
-     * @param optional : is the export optional?
-     * @param from : internal service context
-     * @param to : external bundle context
-     * @param exp : handler
-     */
-    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to, ProvidedService exp) {
-        this.m_destination = to;
-        this.m_origin = from;
-        this.m_ps = exp;
-        try {
-            this.m_filter = to.createFilter(filter);
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-            return;
-        }
-        this.m_aggregate = multiple;
-        this.m_specification = specification;
-        this.m_optional = optional;
-    }
-
-    /**
-     * Start method.
-     * Start the export and the provider tracking. 
-     */
-    public synchronized void start() {
-        try {
-            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
-            if (refs != null) {
-                for (int i = 0; i < refs.length; i++) {
-                    if (m_filter.match(refs[i])) {
-                        Record rec = new Record();
-                        rec.m_ref = refs[i];
-                        m_records.add(rec);
-                    }
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
-        // Publish available services
-        if (m_records.size() > 0) {
-            if (m_aggregate) {
-                for (int i = 0; i < m_records.size(); i++) {
-                    Record rec = (Record) m_records.get(i);
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            } else {
-                Record rec = (Record) m_records.get(0);
-                if (rec.m_reg == null) {
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        }
-
-        // Register service listener
-        try {
-            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
-        } catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
-
-        m_isValid = isSatisfied();
-    }
-
-    /**
-     * Transform service reference property in a dictionary.
-     * instance.name and factory.name are injected too.
-     * @param ref : the service reference.
-     * @return the dictionary containing all property of the given service reference.
-     */
-    private Dictionary getProps(ServiceReference ref) {
-        Properties prop = new Properties();
-        String[] keys = ref.getPropertyKeys();
-        for (int i = 0; i < keys.length; i++) {
-            prop.put(keys[i], ref.getProperty(keys[i]));
-        }
-
-        prop.put("instance.name", m_ps.getManager().getInstanceName());
-        prop.put("factory.name", m_ps.getManager().getFactory().getName());
-
-        return prop;
-    }
-
-    /**
-     * Stop  method.
-     * Remove the service listener and unregister all exported service.
-     */
-    public synchronized void stop() {
-        m_origin.removeServiceListener(this);
-
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            rec.m_svcObject = null;
-            if (rec.m_reg != null) {
-                rec.m_reg.unregister();
-                m_origin.ungetService(rec.m_ref);
-                rec.m_ref = null;
-            }
-        }
-
-        m_records.clear();
-    }
-
-    /**
-     * Check exporter validity.
-     * @return true if the exports is optional, or a service is really exported
-     */
-    public boolean isSatisfied() {
-        return m_optional || m_records.size() > 0;
-    }
-
-    /**
-     * Check if a service is published.
-     * @return true if at least one service is published by this handler
-     */
-    public boolean isPublishing() {
-        return m_records.size() > 0;
-    }
-
-    /**
-     * Get the list of records using the given reference.
-     * @param ref : the service reference
-     * @return the list of records using the given reference, empty if no record used this reference
-     */
-    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
-        List l = new ArrayList();
-        for (int i = 0; i < m_records.size(); i++) {
-            Record rec = (Record) m_records.get(i);
-            if (rec.m_ref == ref) {
-                l.add(rec);
-            }
-        }
-        return l;
-    }
-
-    /**
-     * Service Listener Implementation.
-     * @param ev : the service event
-     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
-     */
-    public void serviceChanged(ServiceEvent ev) {
-        if (ev.getType() == ServiceEvent.REGISTERED) {
-            arrivalManagement(ev.getServiceReference());
-        }
-        if (ev.getType() == ServiceEvent.UNREGISTERING) {
-            departureManagement(ev.getServiceReference());
-        }
-
-        if (ev.getType() == ServiceEvent.MODIFIED) {
-            if (m_filter.match(ev.getServiceReference())) {
-                // Test if the ref is always matching with the filter
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The ref is already contained => update
-                    // the properties
-                    for (int i = 0; i < l.size(); i++) { // Stop the implied
-                        // record
-                        Record rec = (Record) l.get(i);
-                        if (rec.m_reg != null) {
-                            rec.m_reg.setProperties(getProps(rec.m_ref));
-                        }
-                    }
-                } else { // it is a new mathcing service => add it
-                    arrivalManagement(ev.getServiceReference());
-                }
-            } else {
-                List l = getRecordsByRef(ev.getServiceReference());
-                if (l.size() > 0) { // The ref is already contained => the
-                    // service does no more match
-                    departureManagement(ev.getServiceReference());
-                }
-            }
-        }
-    }
-
-    /**
-     * Manage the arrival of a service.
-     * @param ref : the new service reference.
-     */
-    private void arrivalManagement(ServiceReference ref) {
-        // Check if the new service match
-        if (m_filter.match(ref)) {
-            // Add it to the record list
-            Record rec = new Record();
-            rec.m_ref = ref;
-            m_records.add(rec);
-            // Publishing ?
-            if (m_records.size() == 1 || m_aggregate) { // If the service is the
-                // first one, or if it
-                // is a multiple imports
-                rec.m_svcObject = m_origin.getService(rec.m_ref);
-                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-            }
-            // Compute the new state
-            if (!m_isValid && isSatisfied()) {
-                m_isValid = true;
-                m_ps.validating(this);
-            }
-        }
-    }
-
-    /**
-     * Manage the departure of a service.
-     * @param ref : the new service reference.
-     */
-    private void departureManagement(ServiceReference ref) {
-        List l = getRecordsByRef(ref);
-        for (int i = 0; i < l.size(); i++) { // Stop the implied record
-            Record rec = (Record) l.get(i);
-            if (rec.m_reg != null) {
-                rec.m_svcObject = null;
-                rec.m_reg.unregister();
-                rec.m_reg = null;
-                m_origin.ungetService(rec.m_ref);
-            }
-        }
-        m_records.removeAll(l);
-
-        // Check the validity & if we need to reimport the service
-        if (m_records.size() > 0) {
-            // There is other available services
-            if (!m_aggregate) { // Import the next one
-                Record rec = (Record) m_records.get(0);
-                if (rec.m_svcObject == null) { // It is the first service who
-                    // disappears - create the next
-                    // one
-                    rec.m_svcObject = m_origin.getService(rec.m_ref);
-                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
-                }
-            }
-        } else {
-            if (!m_optional) {
-                m_isValid = false;
-                m_ps.invalidating(this);
-            }
-        }
-    }
-
-
-    protected String getSpecification() {
-        return m_specification;
-    }
-
-
-    public String getFilter() {
-        return m_filterStr;
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
similarity index 86%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
index 1ebbcf3..7bdb382 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceReferenceImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
@@ -1,112 +1,112 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Internal service reference implementation. This class is used for in the
- * composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceReferenceImpl implements ServiceReference {
-
-    /**
-     * Service Registration attached to the service reference.
-     */
-    private ServiceRegistrationImpl m_registration = null;
-    
-    /**
-     * Component Instance.
-     */
-    private ComponentInstance m_cm;
-
-    /**
-     * Constructor.
-     * 
-     * @param cm : component instance publishing the service.
-     * @param sr : registration attached to this service reference.
-     */
-    public ServiceReferenceImpl(ComponentInstance cm, ServiceRegistrationImpl sr) {
-        m_registration = sr;
-        m_cm = cm;
-    }
-
-    /**
-     * Not supported in composite.
-     * @return null
-     * @see org.osgi.framework.ServiceReference#getBundle()
-     */
-    public Bundle getBundle() {
-        return m_cm.getContext().getBundle();
-    }
-
-    /**
-     * Get the service registration for this reference.
-     * @return the service registration for this service reference.
-     */
-    public ServiceRegistrationImpl getServiceRegistration() {
-        return m_registration;
-    }
-
-
-    /**
-     * Get a property value.
-     * @param s : the key of the required property.
-     * @return the property value or null if no property for the given key.
-     * @see org.osgi.framework.ServiceReference#getProperty(java.lang.String)
-     */
-    public Object getProperty(String s) {
-        return m_registration.getProperty(s);
-    }
-
-    /**
-     * Get the String arrays of service property keys.
-     * @return : the list of property keys.
-     * @see org.osgi.framework.ServiceReference#getPropertyKeys()
-     */
-    public String[] getPropertyKeys() {
-        return m_registration.getPropertyKeys();
-    }
-
-
-    /**
-     * Unsupported Operation inside composite.
-     * @return bundles using this reference.
-     * @see org.osgi.framework.ServiceReference#getUsingBundles()
-     */
-    public Bundle[] getUsingBundles() {
-        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");
-    }
-
-    /**
-     * Check if the current service reference is assignable to the given bundle.
-     * @param arg0 : the bundle to check
-     * @param arg1 : the class name to check.
-     * @return true in the case of composite
-     * @see org.osgi.framework.ServiceReference#isAssignableTo(org.osgi.framework.Bundle, java.lang.String)
-     */
-    public boolean isAssignableTo(Bundle arg0, String arg1) {
-        return true;
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.context;

+

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

+import org.osgi.framework.Bundle;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Internal service reference implementation. This class is used for in the

+ * composition.

+ * 

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

+ */

+public class ServiceReferenceImpl implements ServiceReference {

+

+    /**

+     * Service Registration attached to the service reference.

+     */

+    private ServiceRegistrationImpl m_registration = null;

+    

+    /**

+     * Component Instance.

+     */

+    private ComponentInstance m_cm;

+

+    /**

+     * Constructor.

+     * 

+     * @param instance : component instance publishing the service.

+     * @param ref : registration attached to this service reference.

+     */

+    public ServiceReferenceImpl(ComponentInstance instance, ServiceRegistrationImpl ref) {

+        m_registration = ref;

+        m_cm = instance;

+    }

+

+    /**

+     * Not supported in composite.

+     * @return null

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

+     */

+    public Bundle getBundle() {

+        return m_cm.getContext().getBundle();

+    }

+

+    /**

+     * Get the service registration for this reference.

+     * @return the service registration for this service reference.

+     */

+    public ServiceRegistrationImpl getServiceRegistration() {

+        return m_registration;

+    }

+

+

+    /**

+     * Get a property value.

+     * @param name : the key of the required property.

+     * @return the property value or null if no property for the given key.

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

+     */

+    public Object getProperty(String name) {

+        return m_registration.getProperty(name);

+    }

+

+    /**

+     * Get the String arrays of service property keys.

+     * @return : the list of property keys.

+     * @see org.osgi.framework.ServiceReference#getPropertyKeys()

+     */

+    public String[] getPropertyKeys() {

+        return m_registration.getPropertyKeys();

+    }

+

+

+    /**

+     * Unsupported Operation inside composite.

+     * @return bundles using this reference.

+     * @see org.osgi.framework.ServiceReference#getUsingBundles()

+     */

+    public Bundle[] getUsingBundles() {

+        throw new UnsupportedOperationException("getUsingBundles is not supported in scope");

+    }

+

+    /**

+     * Check if the current service reference is assignable to the given bundle.

+     * @param arg0 : the bundle to check

+     * @param arg1 : the class name to check.

+     * @return true in the case of composite

+     * @see org.osgi.framework.ServiceReference#isAssignableTo(org.osgi.framework.Bundle, java.lang.String)

+     */

+    public boolean isAssignableTo(Bundle arg0, String arg1) {

+        return true;

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
similarity index 87%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
index 6818899..9cd8edf 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistrationImpl.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
@@ -1,257 +1,257 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.InstanceManager;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Internal service registration implementation. This class is used for in the
- * composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceRegistrationImpl implements ServiceRegistration {
-
-    /**
-     * Service Registry.
-     */
-    private ServiceRegistry m_registry = null;
-
-    /**
-     * Interfaces associated with the service object.
-     */
-    private String[] m_classes = null;
-
-    /**
-     * Service Id associated with the service object.
-     */
-    private Long m_serviceId = null;
-
-    /**
-     * Service object.
-     */
-    private Object m_svcObj = null;
-
-    /**
-     * Service factory interface.
-     */
-    private ServiceFactory m_factory = null;
-
-    /**
-     * Associated property dictionary.
-     */
-    private Map m_propMap = null;
-
-    /**
-     * Re-usable service reference.
-     */
-    private ServiceReferenceImpl m_ref = null;
-
-    /**
-     * Property Keys List.
-     */
-    private List m_list = new ArrayList();
-
-    /**
-     * Constructor.
-     * 
-     * @param registry : the service registry
-     * @param cm : component instance
-     * @param classes : published interfaces array
-     * @param serviceId : the unique service id
-     * @param svcObj : the service object or the service factory object
-     * @param dict : service properties
-     */
-    public ServiceRegistrationImpl(ServiceRegistry registry, ComponentInstance cm, String[] classes, Long serviceId, Object svcObj, Dictionary dict) {
-        m_registry = registry;
-        m_classes = classes;
-        m_serviceId = serviceId;
-        m_svcObj = svcObj;
-        if (m_svcObj instanceof ServiceFactory) { m_factory = (ServiceFactory) m_svcObj; }
-        initializeProperties(dict);
-
-        // This reference is the "standard" reference for this service and will
-        // always be returned by getReference().
-        // Since all reference to this service are supposed to be equal, we use
-        // the hash code of this reference for
-        // a references to this service in ServiceReference.
-        m_ref = new ServiceReferenceImpl(cm, this);
-    }
-
-    /**
-     * Check if the service registration still valid.
-     * @return true if the service registration is valid.
-     */
-    protected boolean isValid() {
-        return m_svcObj != null;
-    }
-
-    /**
-     * Get the service reference attached with this service registration.
-     * @return the service reference
-     * @see org.osgi.framework.ServiceRegistration#getReference()
-     */
-    public ServiceReference getReference() {
-        return m_ref;
-    }
-
-    /**
-     * Add properties to a service registration.
-     * @param dict : the properties to add
-     * @see org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)
-     */
-    public void setProperties(Dictionary dict) {
-        // Make sure registration is valid.
-        if (!isValid()) {
-            throw new IllegalStateException("The service registration is no longer valid.");
-        }
-        // Set the properties.
-        initializeProperties(dict);
-        // Tell registry about it.
-        m_registry.servicePropertiesModified(this);
-    }
-
-    /**
-     * Unregister the service.
-     * @see org.osgi.framework.ServiceRegistration#unregister()
-     */
-    public void unregister() {
-        if (m_svcObj != null) {
-            m_registry.unregisterService(this);
-            m_svcObj = null;
-            m_factory = null;
-        } else {
-            throw new IllegalStateException("Service already unregistered.");
-        }
-    }
-
-    /**
-     * Look for a property in the service properties.
-     * 
-     * @param key : property key
-     * @return the object associated with the key or null if the key is not
-     * present.
-     */
-    protected Object getProperty(String key) {
-        return m_propMap.get(key);
-    }
-
-    /**
-     * Get the property keys.
-     * @return the property keys list.
-     */
-    protected String[] getPropertyKeys() {
-        synchronized (m_propMap) {
-            m_list.clear();
-            Iterator i = m_propMap.entrySet().iterator();
-            while (i.hasNext()) {
-                Map.Entry entry = (Map.Entry) i.next();
-                m_list.add(entry.getKey());
-            }
-            return (String[]) m_list.toArray(new String[m_list.size()]);
-        }
-    }
-
-    /**
-     * Get the service object.
-     * @return the service object. Call the service factory if needed.
-     */
-    protected Object getService() {
-        // If the service object is a service factory, then
-        // let it create the service object.
-        if (m_factory != null) {
-            return getFactoryUnchecked();
-        } else {
-            return m_svcObj;
-        }
-    }
-
-    /**
-     * Initialize properties.
-     * 
-     * @param dict : service properties to publish.
-     */
-    private void initializeProperties(Dictionary dict) {
-        // Create a case insensitive map.
-        if (m_propMap == null) {
-            m_propMap = new StringMap(false);
-        } else {
-            m_propMap.clear();
-        }
-
-        if (dict != null) {
-            Enumeration keys = dict.keys();
-            while (keys.hasMoreElements()) {
-                Object key = keys.nextElement();
-                m_propMap.put(key, dict.get(key));
-            }
-        }
-        // Add the framework assigned properties.
-        m_propMap.put(Constants.OBJECTCLASS, m_classes);
-        m_propMap.put(Constants.SERVICE_ID, m_serviceId);
-    }
-
-    /**
-     * Get a service object via a service factory.
-     * @return the service object via the service factory invocation.
-     */
-    private Object getFactoryUnchecked() {
-        return m_factory.getService(null, this);
-    }
-
-    /**
-     * Unget a service. (Internal Method)
-     * 
-     * @param cm : component instance using the service.
-     * @param svcObj : the unget service object.
-     */
-    private void ungetFactoryUnchecked(ComponentInstance cm, Object svcObj) {
-        if (cm instanceof InstanceManager) {
-            m_factory.ungetService(((InstanceManager) cm).getContext().getBundle(), this, svcObj);
-        }
-
-    }
-
-    /**
-     * Unget a service.
-     * 
-     * @param cm : component instance using the service.
-     * @param srvObj : the unget service object.
-     */
-    public void ungetService(ComponentInstance cm, Object srvObj) {
-        // If the service object is a service factory, then let is release the
-        // service object.
-        if (m_factory != null) {
-            ungetFactoryUnchecked(cm, srvObj);
-        }
-    }
-
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.context;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.Enumeration;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+

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

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

+import org.osgi.framework.Constants;

+import org.osgi.framework.ServiceFactory;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * Internal service registration implementation. This class is used for in the

+ * composition.

+ * 

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

+ */

+public class ServiceRegistrationImpl implements ServiceRegistration {

+

+    /**

+     * Service Registry.

+     */

+    private ServiceRegistry m_registry = null;

+

+    /**

+     * Interfaces associated with the service object.

+     */

+    private String[] m_classes = null;

+

+    /**

+     * Service Id associated with the service object.

+     */

+    private Long m_serviceId = null;

+

+    /**

+     * Service object.

+     */

+    private Object m_svcObj = null;

+

+    /**

+     * Service factory interface.

+     */

+    private ServiceFactory m_factory = null;

+

+    /**

+     * Associated property dictionary.

+     */

+    private Map m_propMap = null;

+

+    /**

+     * Re-usable service reference.

+     */

+    private ServiceReferenceImpl m_ref = null;

+

+    /**

+     * Property Keys List.

+     */

+    private List m_list = new ArrayList();

+

+    /**

+     * Constructor.

+     * 

+     * @param registry : the service registry

+     * @param instance : component instance

+     * @param classes : published interfaces array

+     * @param serviceId : the unique service id

+     * @param svcObj : the service object or the service factory object

+     * @param dict : service properties

+     */

+    public ServiceRegistrationImpl(ServiceRegistry registry, ComponentInstance instance, String[] classes, Long serviceId, Object svcObj, Dictionary dict) {

+        m_registry = registry;

+        m_classes = classes;

+        m_serviceId = serviceId;

+        m_svcObj = svcObj;

+        if (m_svcObj instanceof ServiceFactory) { m_factory = (ServiceFactory) m_svcObj; }

+        initializeProperties(dict);

+

+        // This reference is the "standard" reference for this service and will

+        // always be returned by getReference().

+        // Since all reference to this service are supposed to be equal, we use

+        // the hash code of this reference for

+        // a references to this service in ServiceReference.

+        m_ref = new ServiceReferenceImpl(instance, this);

+    }

+

+    /**

+     * Check if the service registration still valid.

+     * @return true if the service registration is valid.

+     */

+    protected boolean isValid() {

+        return m_svcObj != null;

+    }

+

+    /**

+     * Get the service reference attached with this service registration.

+     * @return the service reference

+     * @see org.osgi.framework.ServiceRegistration#getReference()

+     */

+    public ServiceReference getReference() {

+        return m_ref;

+    }

+

+    /**

+     * Add properties to a service registration.

+     * @param dict : the properties to add

+     * @see org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)

+     */

+    public void setProperties(Dictionary dict) {

+        // Make sure registration is valid.

+        if (!isValid()) {

+            throw new IllegalStateException("The service registration is no longer valid.");

+        }

+        // Set the properties.

+        initializeProperties(dict);

+        // Tell registry about it.

+        m_registry.servicePropertiesModified(this);

+    }

+

+    /**

+     * Unregister the service.

+     * @see org.osgi.framework.ServiceRegistration#unregister()

+     */

+    public void unregister() {

+        if (m_svcObj == null) {

+            throw new IllegalStateException("Service already unregistered.");

+        } else {

+            m_registry.unregisterService(this);

+            m_svcObj = null;

+            m_factory = null;

+        }

+    }

+

+    /**

+     * Look for a property in the service properties.

+     * 

+     * @param key : property key

+     * @return the object associated with the key or null if the key is not

+     * present.

+     */

+    protected Object getProperty(String key) {

+        return m_propMap.get(key);

+    }

+

+    /**

+     * Get the property keys.

+     * @return the property keys list.

+     */

+    protected String[] getPropertyKeys() {

+        synchronized (m_propMap) {

+            m_list.clear();

+            Iterator iterator = m_propMap.entrySet().iterator();

+            while (iterator.hasNext()) {

+                Map.Entry entry = (Map.Entry) iterator.next();

+                m_list.add(entry.getKey());

+            }

+            return (String[]) m_list.toArray(new String[m_list.size()]);

+        }

+    }

+

+    /**

+     * Get the service object.

+     * @return the service object. Call the service factory if needed.

+     */

+    protected Object getService() {

+        // If the service object is a service factory, then

+        // let it create the service object.

+        if (m_factory == null) {

+            return m_svcObj;

+        } else {

+            return getFactoryUnchecked();

+        }

+    }

+

+    /**

+     * Initialize properties.

+     * 

+     * @param dict : service properties to publish.

+     */

+    private void initializeProperties(Dictionary dict) {

+        // Create a case insensitive map.

+        if (m_propMap == null) {

+            m_propMap = new StringMap(false);

+        } else {

+            m_propMap.clear();

+        }

+

+        if (dict != null) {

+            Enumeration keys = dict.keys();

+            while (keys.hasMoreElements()) {

+                Object key = keys.nextElement();

+                m_propMap.put(key, dict.get(key));

+            }

+        }

+        // Add the framework assigned properties.

+        m_propMap.put(Constants.OBJECTCLASS, m_classes);

+        m_propMap.put(Constants.SERVICE_ID, m_serviceId);

+    }

+

+    /**

+     * Get a service object via a service factory.

+     * @return the service object via the service factory invocation.

+     */

+    private Object getFactoryUnchecked() {

+        return m_factory.getService(null, this);

+    }

+

+    /**

+     * Unget a service. (Internal Method)

+     * 

+     * @param instance : component instance using the service.

+     * @param svcObj : the unget service object.

+     */

+    private void ungetFactoryUnchecked(ComponentInstance instance, Object svcObj) {

+        if (instance instanceof InstanceManager) {

+            m_factory.ungetService(((InstanceManager) instance).getContext().getBundle(), this, svcObj);

+        }

+

+    }

+

+    /**

+     * Unget a service.

+     * 

+     * @param instance : component instance using the service.

+     * @param srvObj : the unget service object.

+     */

+    public void ungetService(ComponentInstance instance, Object srvObj) {

+        // If the service object is a service factory, then let is release the

+        // service object.

+        if (m_factory != null) {

+            ungetFactoryUnchecked(instance, srvObj);

+        }

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
similarity index 82%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
index c14c5e4..6eb3d7e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/ServiceRegistry.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
@@ -1,336 +1,344 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Internal Service Registry. This class is used for in the composition.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceRegistry {
-
-    /**
-     * Service Id index.
-     */
-    private long m_serviceId = 1L;
-
-    /**
-     * List of service listeners.
-     */
-    private List m_listeners = new ArrayList(); // ListenerInfo List
-
-    /**
-     * List of service registration.
-     */
-    private List m_regs = new ArrayList();
-
-    /**
-     * A "real" bundle context to create LDAP filter.
-     */
-    private BundleContext m_bc; // BundleContext to create Filter
-
-    /**
-     * Listener info structure.
-     */
-    private class ListenerInfo {
-        /**
-         * Listener object.
-         */
-        private ServiceListener m_listener;
-        /**
-         * Filter associated with the filter.
-         */
-        private Filter m_filter;
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param bc : bundle context.
-     */
-    public ServiceRegistry(BundleContext bc) {
-        m_bc = bc;
-    }
-
-    /**
-     * Add a given service listener with no filter.
-     * 
-     * @param arg0 : the service listener to add
-     */
-    public void addServiceListener(ServiceListener arg0) {
-        ListenerInfo li = new ListenerInfo();
-        li.m_listener = arg0;
-        li.m_filter = null;
-        m_listeners.add(li);
-    }
-
-    /**
-     * Unget a service.
-     * 
-     * @param cm : instance releasing the service.
-     * @param ref : released reference.
-     * @return true if the unget success
-     */
-    public boolean ungetService(ComponentInstance cm, ServiceReference ref) {
-
-        ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-        if (reg.isValid()) {
-            reg.ungetService(cm, reg.getService());
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Unregister a service listener.
-     * 
-     * @param arg0 : the service listener to remove
-     */
-    public void removeServiceListener(ServiceListener arg0) {
-        m_listeners.remove(arg0);
-    }
-
-    /**
-     * Register a service.
-     * 
-     * @param cm : provider instance.
-     * @param clazz : provided interface.
-     * @param svcObj : service object of service factory object.
-     * @param dict : service properties.
-     * @return the created service registration.
-     */
-    public ServiceRegistration registerService(ComponentInstance cm, String clazz, Object svcObj, Dictionary dict) {
-        synchronized (m_regs) {
-            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, cm, new String[] { clazz }, new Long(m_serviceId++), svcObj, dict);
-            m_regs.add(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
-            return reg;
-        }
-    }
-
-    /**
-     * Register a service.
-     * 
-     * @param cm : provider instance.
-     * @param clazzes : provided interfaces.
-     * @param svcObj : service object of service factory object.
-     * @param dict : service properties.
-     * @return the created service registration.
-     */
-    public ServiceRegistration registerService(ComponentInstance cm, String[] clazzes, Object svcObj, Dictionary dict) {
-        synchronized (m_regs) {
-            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, cm, clazzes, new Long(m_serviceId++), svcObj, dict);
-            m_regs.add(reg);
-            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
-            return reg;
-        }
-    }
-
-    /**
-     * Dispatch a service event.
-     * @param event : the service to dispatch
-     */
-    private void fireServiceChanged(ServiceEvent event) {
-        synchronized (m_listeners) {
-            // Iterate on the service listener list to notify service listener
-            for (int i = 0; i < m_listeners.size(); i++) {
-                ListenerInfo li = (ListenerInfo) m_listeners.get(i);
-                ServiceReference sr = event.getServiceReference();
-                if (li.m_filter == null) {
-                    li.m_listener.serviceChanged(event);
-                }
-                if (li.m_filter != null && li.m_filter.match(sr)) {
-                    li.m_listener.serviceChanged(event);
-                }
-            }
-        }
-    }
-
-    /**
-     * Get available (and accessible) service references.
-     * 
-     * @param className : required interface
-     * @param expr : LDAP filter
-     * @return : the list of available service references.
-     * @throws InvalidSyntaxException
-     *             occurs when the LDAP filter is malformed.
-     */
-    public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
-        synchronized (m_regs) {
-            // Define filter if expression is not null.
-            Filter filter = null;
-            if (expr != null) {
-                filter = m_bc.createFilter(expr);
-            }
-
-            List refs = new ArrayList();
-
-            for (int i = 0; i < m_regs.size(); i++) {
-                ServiceRegistrationImpl reg = (ServiceRegistrationImpl) m_regs.get(i);
-                // Determine if the registered services matches the search
-                // criteria.
-                boolean matched = false;
-
-                // If className is null, then look at filter only.
-                if ((className == null) && ((filter == null) || filter.match(reg.getReference()))) {
-                    matched = true;
-                } else if (className != null) {
-                    // If className is not null, then first match the
-                    // objectClass property before looking at the
-                    // filter.
-                    String[] objectClass = (String[]) ((ServiceRegistrationImpl) reg).getProperty(Constants.OBJECTCLASS);
-                    for (int classIdx = 0; classIdx < objectClass.length; classIdx++) {
-                        if (objectClass[classIdx].equals(className) && ((filter == null) || filter.match(reg.getReference()))) {
-                            matched = true;
-                            break;
-                        }
-                    }
-                }
-
-                // Add reference if it was a match.
-                if (matched) {
-                    refs.add(reg.getReference());
-                }
-            }
-
-            if (refs.size() > 0) {
-                return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Look for a service reference.
-     * 
-     * @param clazz : required interface.
-     * @return the first available provider or null if none available.
-     */
-    public ServiceReference getServiceReference(String clazz) {
-        synchronized (m_regs) {
-            try {
-                ServiceReference[] refs = getServiceReferences(clazz, null);
-                if (refs != null) {
-                    return refs[0];
-                } // If the refs != null we are sure that it exists one reference or more.
-            } catch (InvalidSyntaxException ex) {
-                System.err.println("Scope Service Registry : Problem when looking for service reference" + ex.getMessage());
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Get a service object.
-     * @param cm : component instance requiring the service.
-     * @param ref : the required reference.
-     * @return the service object.
-     */
-    public Object getService(ComponentInstance cm, ServiceReference ref) {
-        synchronized (m_regs) {
-            // Look for the service registration for this ref
-            ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
-            if (reg.isValid()) {
-                // Delegate the service providing to the service registration
-                return reg.getService();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Get all service references consistent with the given interface and
-     * filter.
-     * @param clazz : the required interface.
-     * @param filter : the LDAP filter.
-     * @return the list of all service reference or null if none available.
-     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
-     */
-    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
-        synchronized (m_regs) {
-            // Can delegate on getServiceReference, indeed their is no test on
-            // the "modularity" conflict.
-            return getServiceReferences(clazz, filter);
-        }
-    }
-
-    /**
-     * Add a service listener with a filter.
-     * @param listener : the service listener to add
-     * @param filter : LDAP filter
-     */
-    public void addServiceListener(ServiceListener listener, String filter) {
-        // If the filter is null, subscribe with no filter.
-        if (filter == null) {
-            addServiceListener(listener);
-            return;
-        }
-        
-        ListenerInfo li = new ListenerInfo();
-        li.m_listener = listener;
-        try {
-            li.m_filter = m_bc.createFilter(filter);
-        } catch (InvalidSyntaxException ex) {
-            System.err.println("Scope Service Registry : Problem when creating a service listener " + ex.getMessage());
-        }
-        m_listeners.add(li);
-    }
-
-    /**
-     * Dispatch a service properties modified event.
-     * @param reg : the implicated service registration.
-     */
-    public void servicePropertiesModified(ServiceRegistrationImpl reg) {
-        fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
-    }
-
-    /**
-     * Unregister a service.
-     * @param reg : the service registration to unregister
-     */
-    public void unregisterService(ServiceRegistrationImpl reg) {
-        m_regs.remove(reg);
-        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
-    }
-
-    /**
-     * Reset the service registry.
-     */
-    protected void reset() {
-        m_serviceId = 1L;
-        m_listeners = new ArrayList();
-        m_regs = new ArrayList();
-    }
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.context;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

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

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

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Constants;

+import org.osgi.framework.Filter;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceEvent;

+import org.osgi.framework.ServiceListener;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * Internal Service Registry. This class is used for in the composition.

+ * 

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

+ */

+public class ServiceRegistry {

+

+    /**

+     * Service Id index.

+     */

+    private long m_serviceId = 1L;

+

+    /**

+     * List of service listeners.

+     */

+    private List m_listeners = new ArrayList(); // ListenerInfo List

+

+    /**

+     * List of service registration.

+     */

+    private List m_regs = new ArrayList();

+

+    /**

+     * A "real" bundle context to create LDAP filter.

+     */

+    private BundleContext m_context; // BundleContext to create Filter

+    

+    /**

+     * Registry logger.

+     */

+    private Logger m_logger;

+

+    /**

+     * Listener info structure.

+     */

+    private class ListenerInfo {

+        /**

+         * Listener object.

+         */

+        private ServiceListener m_listener;

+        /**

+         * Filter associated with the filter.

+         */

+        private Filter m_filter;

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param context : bundle context.

+     */

+    public ServiceRegistry(BundleContext context) {

+        m_context = context;

+        m_logger = new Logger(m_context, "Registry logger " + m_context.getBundle().getBundleId());

+    }

+

+    /**

+     * Add a given service listener with no filter.

+     * 

+     * @param arg0 : the service listener to add

+     */

+    public void addServiceListener(ServiceListener arg0) {

+        ListenerInfo info = new ListenerInfo();

+        info.m_listener = arg0;

+        info.m_filter = null;

+        m_listeners.add(info);

+    }

+

+    /**

+     * Unget a service.

+     * 

+     * @param instance : instance releasing the service.

+     * @param ref : released reference.

+     * @return true if the unget success

+     */

+    public boolean ungetService(ComponentInstance instance, ServiceReference ref) {

+

+        ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();

+        if (reg.isValid()) {

+            reg.ungetService(instance, reg.getService());

+            return true;

+        } else {

+            return false;

+        }

+    }

+

+    /**

+     * Unregister a service listener.

+     * 

+     * @param arg0 : the service listener to remove

+     */

+    public void removeServiceListener(ServiceListener arg0) {

+        m_listeners.remove(arg0);

+    }

+

+    /**

+     * Register a service.

+     * 

+     * @param instance : provider instance.

+     * @param clazz : provided interface.

+     * @param svcObj : service object of service factory object.

+     * @param dict : service properties.

+     * @return the created service registration.

+     */

+    public ServiceRegistration registerService(ComponentInstance instance, String clazz, Object svcObj, Dictionary dict) {

+        synchronized (m_regs) {

+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, new String[] { clazz }, new Long(m_serviceId++), svcObj, dict);

+            m_regs.add(reg);

+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));

+            return reg;

+        }

+    }

+

+    /**

+     * Register a service.

+     * 

+     * @param instance : provider instance.

+     * @param clazzes : provided interfaces.

+     * @param svcObj : service object of service factory object.

+     * @param dict : service properties.

+     * @return the created service registration.

+     */

+    public ServiceRegistration registerService(ComponentInstance instance, String[] clazzes, Object svcObj, Dictionary dict) {

+        synchronized (m_regs) {

+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, clazzes, new Long(m_serviceId++), svcObj, dict);

+            m_regs.add(reg);

+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));

+            return reg;

+        }

+    }

+

+    /**

+     * Dispatch a service event.

+     * @param event : the service to dispatch

+     */

+    private void fireServiceChanged(ServiceEvent event) {

+        synchronized (m_listeners) {

+            // Iterate on the service listener list to notify service listener

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

+                ListenerInfo info = (ListenerInfo) m_listeners.get(i);

+                ServiceReference ref = event.getServiceReference();

+                if (info.m_filter == null) {

+                    info.m_listener.serviceChanged(event);

+                }

+                if (info.m_filter != null && info.m_filter.match(ref)) {

+                    info.m_listener.serviceChanged(event);

+                }

+            }

+        }

+    }

+

+    /**

+     * Get available (and accessible) service references.

+     * 

+     * @param className : required interface

+     * @param expr : LDAP filter

+     * @return : the list of available service references.

+     * @throws InvalidSyntaxException

+     *             occurs when the LDAP filter is malformed.

+     */

+    public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {

+        synchronized (m_regs) {

+            // Define filter if expression is not null.

+            Filter filter = null;

+            if (expr != null) {

+                filter = m_context.createFilter(expr);

+            }

+

+            List refs = new ArrayList();

+

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

+                ServiceRegistrationImpl reg = (ServiceRegistrationImpl) m_regs.get(i);

+                // Determine if the registered services matches the search

+                // criteria.

+                boolean matched = false;

+

+                // If className is null, then look at filter only.

+                if ((className == null) && ((filter == null) || filter.match(reg.getReference()))) {

+                    matched = true;

+                } else if (className != null) {

+                    // If className is not null, then first match the

+                    // objectClass property before looking at the

+                    // filter.

+                    String[] objectClass = (String[]) ((ServiceRegistrationImpl) reg).getProperty(Constants.OBJECTCLASS);

+                    for (int classIdx = 0; classIdx < objectClass.length; classIdx++) {

+                        if (objectClass[classIdx].equals(className) && ((filter == null) || filter.match(reg.getReference()))) {

+                            matched = true;

+                            break;

+                        }

+                    }

+                }

+

+                // Add reference if it was a match.

+                if (matched) {

+                    refs.add(reg.getReference());

+                }

+            }

+

+            if (! refs.isEmpty()) {

+                return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);

+            }

+            return null;

+        }

+    }

+

+    /**

+     * Look for a service reference.

+     * 

+     * @param clazz : required interface.

+     * @return the first available provider or null if none available.

+     */

+    public ServiceReference getServiceReference(String clazz) {

+        synchronized (m_regs) {

+            try {

+                ServiceReference[] refs = getServiceReferences(clazz, null);

+                if (refs != null) {

+                    return refs[0];

+                } // If the refs != null we are sure that it exists one reference or more.

+            } catch (InvalidSyntaxException ex) {

+                // Cannot happen : null filter.

+            }

+            return null;

+        }

+    }

+

+    /**

+     * Get a service object.

+     * @param instance : component instance requiring the service.

+     * @param ref : the required reference.

+     * @return the service object.

+     */

+    public Object getService(ComponentInstance instance, ServiceReference ref) {

+        synchronized (m_regs) {

+            // Look for the service registration for this ref

+            ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();

+            if (reg.isValid()) {

+                // Delegate the service providing to the service registration

+                return reg.getService();

+            } else {

+                return null;

+            }

+        }

+    }

+

+    /**

+     * Get all service references consistent with the given interface and

+     * filter.

+     * @param clazz : the required interface.

+     * @param filter : the LDAP filter.

+     * @return the list of all service reference or null if none available.

+     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.

+     */

+    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {

+        synchronized (m_regs) {

+            // Can delegate on getServiceReference, indeed their is no test on

+            // the "modularity" conflict.

+            return getServiceReferences(clazz, filter);

+        }

+    }

+

+    /**

+     * Add a service listener with a filter.

+     * @param listener : the service listener to add

+     * @param filter : LDAP filter

+     */

+    public void addServiceListener(ServiceListener listener, String filter) {

+        // If the filter is null, subscribe with no filter.

+        if (filter == null) {

+            addServiceListener(listener);

+            return;

+        }

+        

+        try {

+            ListenerInfo info = new ListenerInfo();

+            info.m_listener = listener;

+            info.m_filter = m_context.createFilter(filter);

+            m_listeners.add(info);

+        } catch (InvalidSyntaxException ex) {

+            m_logger.log(Logger.ERROR, ex.getMessage(), ex);

+        }

+        

+    }

+

+    /**

+     * Dispatch a service properties modified event.

+     * @param reg : the implicated service registration.

+     */

+    public void servicePropertiesModified(ServiceRegistrationImpl reg) {

+        fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));

+    }

+

+    /**

+     * Unregister a service.

+     * @param reg : the service registration to unregister

+     */

+    public void unregisterService(ServiceRegistrationImpl reg) {

+        m_regs.remove(reg);

+        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));

+    }

+

+    /**

+     * Reset the service registry.

+     */

+    public void reset() {

+        m_serviceId = 1L;

+        m_listeners = new ArrayList();

+        m_regs = new ArrayList();

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
similarity index 80%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
index bd057aa..31f7331 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
@@ -1,142 +1,142 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.composite;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Simple utility class that creates a map for string-based keys by extending
- * <tt>TreeMap</tt>. This map can be set to use case-sensitive or
- * case-insensitive comparison when searching for the key. Any keys put into
- * this map will be converted to a <tt>String</tt> using the
- * <tt>toString()</tt> method, since it is only intended to compare strings.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class StringMap extends TreeMap {
-
-    /**
-     * serialVersionUID.
-     */
-    private static final long serialVersionUID = 6948801857034259744L;
-
-    /**
-     * Constructor.
-     */
-    public StringMap() {
-        this(true);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param caseSensitive : fix if the map if case sensitive or not.
-     */
-    public StringMap(boolean caseSensitive) {
-        super(new StringComparator(caseSensitive));
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param map : initial properties.
-     * @param caseSensitive : fix if the map if case sensitive or not.
-     */
-    public StringMap(Map map, boolean caseSensitive) {
-        this(caseSensitive);
-        putAll(map);
-    }
-
-    /**
-     * Put a record in the map.
-     * @param key : key
-     * @param value : value
-     * @return an object.
-     * @see java.util.TreeMap#put(K, V)
-     */
-    public Object put(Object key, Object value) {
-        return super.put(key.toString(), value);
-    }
-
-    /**
-     * Check if the map is case-sensitive.
-     * @return true if the map is case sensitive.
-     */
-    public boolean isCaseSensitive() {
-        return ((StringComparator) comparator()).isCaseSensitive();
-    }
-
-    /**
-     * Set the case sensitivity.
-     * 
-     * @param b : the new case sensitivity.
-     */
-    public void setCaseSensitive(boolean b) {
-        ((StringComparator) comparator()).setCaseSensitive(b);
-    }
-
-    private static class StringComparator implements Comparator {
-        /**
-         * Is the map case sensitive?
-         */
-        private boolean m_isCaseSensitive = true;
-
-        /**
-         * Constructor.
-         * 
-         * @param b : true to enable the case sensitivity.
-         */
-        public StringComparator(boolean b) {
-            m_isCaseSensitive = b;
-        }
-
-        /**
-         * Compare to object.
-         * @param o1 : first object to compare
-         * @param o2 : second object to compare
-         * @return the comparison result
-         * @see java.util.Comparator#compare(T, T)
-         */
-        public int compare(Object o1, Object o2) {
-            if (m_isCaseSensitive) {
-                return o1.toString().compareTo(o2.toString());
-            } else {
-                return o1.toString().compareToIgnoreCase(o2.toString());
-            }
-        }
-
-        /**
-         * Check if the comparator is case sensitive.
-         * @return true if the map is case sensitive.
-         */
-        public boolean isCaseSensitive() {
-            return m_isCaseSensitive;
-        }
-
-        /**
-         * Set the case sensitivity.
-         * 
-         * @param b : true to enable the case sensitivity
-         */
-        public void setCaseSensitive(boolean b) {
-            m_isCaseSensitive = b;
-        }
-    }
-}
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.context;

+

+import java.util.Comparator;

+import java.util.Map;

+import java.util.TreeMap;

+

+/**

+ * Simple utility class that creates a map for string-based keys by extending

+ * <tt>TreeMap</tt>. This map can be set to use case-sensitive or

+ * case-insensitive comparison when searching for the key. Any keys put into

+ * this map will be converted to a <tt>String</tt> using the

+ * <tt>toString()</tt> method, since it is only intended to compare strings.

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

+ */

+public class StringMap extends TreeMap {

+

+    /**

+     * serialVersionUID.

+     */

+    private static final long serialVersionUID = 6948801857034259744L;

+

+    /**

+     * Constructor.

+     */

+    public StringMap() {

+        this(true);

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param caseSensitive : fix if the map if case sensitive or not.

+     */

+    public StringMap(boolean caseSensitive) {

+        super(new StringComparator(caseSensitive));

+    }

+

+    /**

+     * Constructor.

+     * 

+     * @param map : initial properties.

+     * @param caseSensitive : fix if the map if case sensitive or not.

+     */

+    public StringMap(Map map, boolean caseSensitive) {

+        this(caseSensitive);

+        putAll(map);

+    }

+

+    /**

+     * Put a record in the map.

+     * @param key : key

+     * @param value : value

+     * @return an object.

+     * @see java.util.TreeMap#put(K, V)

+     */

+    public Object put(Object key, Object value) {

+        return super.put(key.toString(), value);

+    }

+

+    /**

+     * Check if the map is case-sensitive.

+     * @return true if the map is case sensitive.

+     */

+    public boolean isCaseSensitive() {

+        return ((StringComparator) comparator()).isCaseSensitive();

+    }

+

+    /**

+     * Set the case sensitivity.

+     * 

+     * @param flag : the new case sensitivity.

+     */

+    public void setCaseSensitive(boolean flag) {

+        ((StringComparator) comparator()).setCaseSensitive(flag);

+    }

+

+    private static class StringComparator implements Comparator {

+        /**

+         * Is the map case sensitive?

+         */

+        private boolean m_isCaseSensitive = true;

+

+        /**

+         * Constructor.

+         * 

+         * @param flag : true to enable the case sensitivity.

+         */

+        public StringComparator(boolean flag) {

+            m_isCaseSensitive = flag;

+        }

+

+        /**

+         * Compare to object.

+         * @param object1 : first object to compare

+         * @param object2 : second object to compare

+         * @return the comparison result

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

+         */

+        public int compare(Object object1, Object object2) {

+            if (m_isCaseSensitive) {

+                return object1.toString().compareTo(object2.toString());

+            } else {

+                return object1.toString().compareToIgnoreCase(object2.toString());

+            }

+        }

+

+        /**

+         * Check if the comparator is case sensitive.

+         * @return true if the map is case sensitive.

+         */

+        public boolean isCaseSensitive() {

+            return m_isCaseSensitive;

+        }

+

+        /**

+         * Set the case sensitivity.

+         * 

+         * @param flag : true to enable the case sensitivity

+         */

+        public void setCaseSensitive(boolean flag) {

+            m_isCaseSensitive = flag;

+        }

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index 1509cf6..6021c5a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -24,7 +24,6 @@
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.ipojo.architecture.InstanceDescription;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
 
 /**
  * Architecture Handler : do reflection on your component.
@@ -52,6 +51,7 @@
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
+        // Nothing do do when stopping.
     }
 
     /**
@@ -59,7 +59,7 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        log(Logger.INFO, "Start architecture handler with " + m_name + " name");
+        info("Start architecture handler with " + m_name + " name");
     }
 
     /**
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
deleted file mode 100644
index 26db364..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ /dev/null
@@ -1,688 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.handlers.configuration;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.parser.ParseUtils;
-import org.apache.felix.ipojo.util.Callback;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Configurable Property.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ConfigurableProperty {
-
-    /**
-     * Name of the property (filed name if not set).
-     */
-    private String m_name;
-
-    /**
-     * Field of the property.
-     */
-    private String m_field;
-
-    /**
-     * Method of the property.
-     */
-    private Callback m_method;
-
-    /**
-     * Value of the property.
-     */
-    private Object m_value;
-
-    /**
-     * Type of the property.
-     */
-    private Class m_type;
-
-    /**
-     * Configuration Handler managing this property.
-     */
-    private ConfigurationHandler m_handler;
-
-    /**
-     * Configurable Property Constructor. At least the method or the field need
-     * to be referenced.
-     * 
-     * @param name : name of the property (optional)
-     * @param field : name of the field
-     * @param method : method name
-     * @param value : initial value of the property (optional)
-     * @param type : the type of the property
-     * @param ch : configuration handler managing this configurable property
-     * @throws ConfigurationException : occurs when the property value cannot be set.
-     */
-    public ConfigurableProperty(String name, String field, String method, String value, String type, ConfigurationHandler ch) throws ConfigurationException {
-        m_handler = ch;
-
-        m_field = field;
-
-        if (name != null) {
-            m_name = name;
-        } else {
-            if (m_field != null) {
-                m_name = field;
-            } else {
-                m_name = method;
-            }
-        }
-        m_field = field;
-
-        if (value != null) {
-            setValue(value, type);
-        } else {
-            setType(type);
-        }
-
-        if (method != null) {
-            m_method = new Callback(method, new String[] { m_type.getName() }, false, m_handler.getInstanceManager());
-        }
-
-    }
-
-    /**
-     * The set type method fix the property type according to the given type name.
-     * @param type : the type name
-     * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.
-     */
-    private void setType(String type) throws ConfigurationException {
-        // Syntactic sugar to avoid writing java.lang.String
-        if ("string".equals(type) || "String".equals(type)) {
-            m_type = java.lang.String.class;
-            return;
-        }
-        if (type.equals("boolean")) {
-            m_type = Boolean.TYPE;
-            return;
-        }
-        if ("byte".equals(type)) {
-            m_type = Byte.TYPE;
-            return;
-        }
-        if ("short".equals(type)) {
-            m_type = Short.TYPE;
-            return;
-        }
-        if ("int".equals(type)) {
-            m_type = Integer.TYPE;
-            return;
-        }
-        if ("long".equals(type)) {
-            m_type = Long.TYPE;
-            return;
-        }
-        if ("float".equals(type)) {
-            m_type = Float.TYPE;
-            return;
-        }
-        if ("double".equals(type)) {
-            m_type = Double.TYPE;
-            return;
-        }
-        if ("char".equals(type)) {
-            m_type = Character.TYPE;
-            return;
-        }
-
-        // Array :
-        if (type.endsWith("[]")) {
-            String internalType = type.substring(0, type.length() - 2);
-            if ("string".equals(internalType) || "String".equals(internalType)) {
-                m_type = new String[0].getClass();
-                return;
-            }
-            if ("boolean".equals(internalType)) {
-                m_type = new boolean[0].getClass();
-                return;
-            }
-            if ("byte".equals(internalType)) {
-                m_type = new byte[0].getClass();
-                return;
-            }
-            if ("short".equals(internalType)) {
-                m_type = new short[0].getClass();
-                return;
-            }
-            if ("int".equals(internalType)) {
-                m_type = new int[0].getClass();
-                return;
-            }
-            if ("long".equals(internalType)) {
-                m_type = new long[0].getClass();
-                return;
-            }
-            if ("float".equals(internalType)) {
-                m_type = new float[0].getClass();
-                return;
-            }
-            if ("double".equals(internalType)) {
-                m_type = new double[0].getClass();
-                return;
-            }
-            if ("char".equals(internalType)) {
-                m_type = new char[0].getClass();
-                return;
-            }
-
-            // Complex array type.
-            try {
-                Class c = m_handler.getInstanceManager().getContext().getBundle().loadClass(internalType);
-                Object[] ob = (Object[]) Array.newInstance(c, 0);
-                m_type = ob.getClass();
-                return;
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Class not found exception in setValue on " + internalType);
-            } catch (SecurityException e) {
-                throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);
-            } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
-            }
-        }
-
-        // Non array, complex type.
-        try {
-            m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
-        } catch (ClassNotFoundException e) {
-            throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-        }
-    }
-
-    /**
-     * Set the value of the property.
-     * @param strValue : value of the property (String)
-     * @param type : type of the property
-     * @throws ConfigurationException : occurs when the property value cannot be initialized.
-     */
-    private void setValue(String strValue, String type) throws ConfigurationException {
-        Object value = null;
-
-        // Syntactic sugar to avoid writing java.lang.String
-        if ("string".equals(type) || "String".equals(type)) {
-            value = new String(strValue);
-            m_type = java.lang.String.class;
-        }
-        if (type.equals("boolean")) {
-            value = new Boolean(strValue);
-            m_type = Boolean.TYPE;
-        }
-        if ("byte".equals(type)) {
-            value = new Byte(strValue);
-            m_type = Byte.TYPE;
-        }
-        if ("short".equals(type)) {
-            value = new Short(strValue);
-            m_type = Short.TYPE;
-        }
-        if ("int".equals(type)) {
-            value = new Integer(strValue);
-            m_type = Integer.TYPE;
-        }
-        if ("long".equals(type)) {
-            value = new Long(strValue);
-            m_type = Long.TYPE;
-        }
-        if ("float".equals(type)) {
-            value = new Float(strValue);
-            m_type = Float.TYPE;
-        }
-        if ("double".equals(type)) {
-            value = new Double(strValue);
-            m_type = Double.TYPE;
-        }
-        if ("char".equals(type)) {
-            value = new Character(strValue.charAt(0));
-            m_type = Character.TYPE;
-        }
-
-        // Array :
-        if (type.endsWith("[]")) {
-            String internalType = type.substring(0, type.length() - 2);
-            setArrayValue(internalType, ParseUtils.parseArrays(strValue));
-            return;
-        }
-
-        if (value == null) {
-            // Else it is a neither a primitive type neither a String -> create
-            // the object by calling a constructor with a string in argument.
-            try {
-                m_type = m_handler.getInstanceManager().getContext().getBundle().loadClass(type);
-                Constructor cst = m_type.getConstructor(new Class[] { String.class });
-                value = cst.newInstance(new Object[] { strValue });
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
-            } catch (SecurityException e) {
-                throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());
-            } catch (NoSuchMethodException e) {
-                throw new ConfigurationException("Constructor not found exeption in setValue on " + type + " : " + e.getMessage());
-            } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Instantiation problem  " + type);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Illegal Access " + type);
-            } catch (InvocationTargetException e) {
-                throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
-            }
-        }
-
-        m_value = value;
-
-    }
-
-    /**
-     * Set array value to the current property.
-     * 
-     * @param internalType : type of the property
-     * @param values : new property value
-     * @throws ConfigurationException occurs when the array cannot be initialized
-     */
-    private void setArrayValue(String internalType, String[] values) throws ConfigurationException {
-        if ("string".equals(internalType) || "String".equals(internalType)) {
-            String[] str = new String[values.length];
-            for (int i = 0; i < values.length; i++) {
-                str[i] = new String(values[i]);
-            }
-            m_value = str;
-            m_type = new String[0].getClass();
-            return;
-        }
-        if ("boolean".equals(internalType)) {
-            boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) {
-                bool[i] = new Boolean(values[i]).booleanValue();
-            }
-            m_value = bool;
-            m_type = new boolean[0].getClass();
-            return;
-        }
-        if ("byte".equals(internalType)) {
-            byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) {
-                byt[i] = new Byte(values[i]).byteValue();
-            }
-            m_value = byt;
-            m_type = new byte[0].getClass();
-            return;
-        }
-        if ("short".equals(internalType)) {
-            short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) {
-                shor[i] = new Short(values[i]).shortValue();
-            }
-            m_value = shor;
-            m_type = new short[0].getClass();
-            return;
-        }
-        if ("int".equals(internalType)) {
-            int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) {
-                in[i] = new Integer(values[i]).intValue();
-            }
-            m_value = in;
-            m_type = new int[0].getClass();
-            return;
-        }
-        if ("long".equals(internalType)) {
-            long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) {
-                ll[i] = new Long(values[i]).longValue();
-            }
-            m_value = ll;
-            m_type = new long[0].getClass();
-            return;
-        }
-        if ("float".equals(internalType)) {
-            float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) {
-                fl[i] = new Float(values[i]).floatValue();
-            }
-            m_value = fl;
-            m_type = new float[0].getClass();
-            return;
-        }
-        if ("double".equals(internalType)) {
-            double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = new Double(values[i]).doubleValue();
-            }
-            m_value = dl;
-            m_type = new double[0].getClass();
-            return;
-        }
-        if ("char".equals(internalType)) {
-            char[] dl = new char[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = values[i].toCharArray()[0];
-            }
-            m_value = dl;
-            m_type = new char[0].getClass();
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_handler.getInstanceManager().getContext().getBundle().loadClass(internalType);
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(c, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i].trim() });
-            }
-            m_value = ob;
-            m_type = ob.getClass();
-            return;
-        } catch (ClassNotFoundException e) {
-            throw new ConfigurationException("Class not found exception in setValue on " + internalType);
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in setValue on " + internalType);
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + internalType);
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access Exception in  " + internalType);
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + internalType + " : " + e.getTargetException().getMessage());
-        }
-    }
-
-    public String getName() {
-        return m_name;
-    }
-
-    public String getField() {
-        return m_field;
-    }
-
-    /**
-     * Get method name, null if no method.
-     * @return the method name.
-     */
-    public String getMethod() {
-        if (m_method == null) { return null; }
-        return m_method.getMethod();
-    }
-
-    /**
-     * Check if the property has a method callback.
-     * @return true if the property has a method.
-     */
-    public boolean hasMethod() {
-        return m_method != null;
-    }
-
-    /**
-     * Check if the property has a field.
-     * @return true if the property has a field.
-     */
-    public boolean hasField() {
-        return m_field != null;
-    }
-
-    public Object getValue() {
-        return m_value;
-    }
-
-    /**
-     * Fix the value of the property.
-     * @param value : the new value.
-     */
-    public void setValue(Object value) {
-        // Is the object is directly assignable to the property, affect it.
-        if (isAssignable(m_type, value)) {
-            m_value = value;
-        } else {
-            // If the object is a String, we must recreate the object from the String form
-            if (value instanceof String) {
-                try {
-                    m_value = create(m_type, (String) value);
-                } catch (ConfigurationException e) {
-                    throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());
-                }
-            } else {
-                // Error, the given property cannot be injected.
-                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, " + value.getClass() + " received");
-            }
-        }
-    }
-    
-    /**
-     * Test if the given value is assignable to the given type.
-     * @param type : class of the type
-     * @param value : object to check
-     * @return true if the object is assignable in the property of type 'type'.
-     */
-    public static boolean isAssignable(Class type, Object value) {
-        if (type.isInstance(value)) {
-            return true;
-        } else if (type.isPrimitive()) {
-            // Manage all boxing types.
-            if (value instanceof Boolean && type.equals(Boolean.TYPE)) {
-                return true;
-            }
-            if (value instanceof Byte && type.equals(Byte.TYPE)) {
-                return true;
-            }
-            if (value instanceof Short && type.equals(Short.TYPE)) {
-                return true;
-            }
-            if (value instanceof Integer && type.equals(Integer.TYPE)) {
-                return true;
-            }
-            if (value instanceof Long && type.equals(Long.TYPE)) {
-                return true;
-            }
-            if (value instanceof Float && type.equals(Float.TYPE)) {
-                return true;
-            }
-            if (value instanceof Double && type.equals(Double.TYPE)) {
-                return true;
-            }
-            if (value instanceof Character && type.equals(Character.TYPE)) {
-                return true;
-            }
-            return false;
-        } else {
-            // Else return false.
-            return false;
-        }
-    }
-
-    /**
-     * Create an object of the given type with the given String value.
-     * @param type : type of the returned object
-     * @param strValue : String value.
-     * @return the object of type 'type' created from the String 'value'
-     * @throws ConfigurationException occurs when the object cannot be created.
-     */
-    public static Object create(Class type, String strValue) throws ConfigurationException {
-        if (type.equals(Boolean.TYPE)) { return new Boolean(strValue); }
-        if (type.equals(Byte.TYPE)) { return new Byte(strValue); }
-        if (type.equals(Short.TYPE)) { return new Short(strValue); }
-        if (type.equals(Integer.TYPE)) { return new Integer(strValue); }
-        if (type.equals(Long.TYPE)) { return new Long(strValue); }
-        if (type.equals(Float.TYPE)) { return new Float(strValue); }
-        if (type.equals(Double.TYPE)) { return new Double(strValue); }
-        if (type.equals(Character.TYPE)) { return new Character(strValue.charAt(0)); }
-
-        // Array :
-        if (type.isArray()) { return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue)); }
-        // Else it is a neither a primitive type neither a String -> create
-        // the object by calling a constructor with a string in argument.
-        try {
-            Constructor cst = type.getConstructor(new Class[] { String.class });
-            return cst.newInstance(new Object[] { strValue });
-        } catch (SecurityException e) {
-            throw new ConfigurationException("Security exception in create on " + type + " : " + e.getMessage());
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in create on " + type + " : " + e.getMessage());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + type);
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access " + type);
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());
-        }
-
-    }
-
-    /**
-     * Create an array object containing the type 'interntype' from the String array 'values'.
-     * @param interntype : internal type of the array.
-     * @param values : String array
-     * @return the array containing objects created from the 'values' array
-     * @throws ConfigurationException occurs when the array cannot be created correctly
-     */
-    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {
-        if (interntype.equals(Boolean.TYPE)) {
-            boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) {
-                bool[i] = new Boolean(values[i]).booleanValue();
-            }
-            return bool;
-        }
-        if (interntype.equals(Byte.TYPE)) {
-            byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) {
-                byt[i] = new Byte(values[i]).byteValue();
-            }
-            return byt;
-        }
-        if (interntype.equals(Short.TYPE)) {
-            short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) {
-                shor[i] = new Short(values[i]).shortValue();
-            }
-            return shor;
-        }
-        if (interntype.equals(Integer.TYPE)) {
-            int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) {
-                in[i] = new Integer(values[i]).intValue();
-            }
-            return in;
-        }
-        if (interntype.equals(Long.TYPE)) {
-            long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) {
-                ll[i] = new Long(values[i]).longValue();
-            }
-            return ll;
-        }
-        if (interntype.equals(Float.TYPE)) {
-            float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) {
-                fl[i] = new Float(values[i]).floatValue();
-            }
-            return fl;
-        }
-        if (interntype.equals(Double.TYPE)) {
-            double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = new Double(values[i]).doubleValue();
-            }
-            return dl;
-        }
-        if (interntype.equals(Character.TYPE)) {
-            char[] dl = new char[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = values[i].toCharArray()[0];
-            }
-            return dl;
-        }
-
-        // Else it is a neither a primitive type -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Constructor cst = interntype.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(interntype, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i].trim() });
-            }
-            return ob;
-        } catch (NoSuchMethodException e) {
-            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());
-        } catch (IllegalArgumentException e) {
-            throw new ConfigurationException("Argument problem to call the constructor of the type " + interntype.getName());
-        } catch (InstantiationException e) {
-            throw new ConfigurationException("Instantiation problem  " + interntype.getName());
-        } catch (IllegalAccessException e) {
-            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());
-        } catch (InvocationTargetException e) {
-            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());
-        }
-    }
-
-    /**
-     * Invoke the method (if specified).
-     * If the invocation failed, the instance is stopped.
-     */
-    public void invoke() {
-        try {
-            m_method.call(new Object[] { m_value });
-        } catch (NoSuchMethodException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_handler.log(Logger.ERROR, "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Handler createInstance method. This method is override to allow delayed callback invocation.
-     * If the invocation failed, the instance is stopped.
-     * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
-     */
-    public void invoke(Object instance) {
-        try {
-            m_method.call(instance, new Object[] { m_value });
-        } catch (NoSuchMethodException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-            m_handler.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 186caa9..ef89f07 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -18,24 +18,23 @@
  */
 package org.apache.felix.ipojo.handlers.configuration;
 
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.IPojoConfiguration;
+import org.apache.felix.ipojo.HandlerFactory;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Property;
 
 /**
  * Handler managing the Configuration Admin.
@@ -46,7 +45,7 @@
     /**
      * List of the configurable fields.
      */
-    private ConfigurableProperty[] m_configurableProperties = new ConfigurableProperty[0];
+    private Property[] m_configurableProperties = new Property[0];
 
     /**
      * ProvidedServiceHandler of the component. It is useful to propagate
@@ -71,16 +70,16 @@
 
     /**
      * Initialize the component type.
-     * @param cd : component type description to populate.
+     * @param desc : component type description to populate.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : metadata are incorrect.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         Element[] confs = metadata.getElements("Properties", "");
-        if (confs.length == 0) { return; }
+        if (confs == null) { return; }
         Element[] configurables = confs[0].getElements("Property");
-        for (int i = 0; i < configurables.length; i++) {
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
             
@@ -90,10 +89,10 @@
 
             String name = configurables[i].getAttribute("name");
             if (name == null) {
-                if (fieldName != null) {
-                    name = fieldName;
-                } else {
+                if (fieldName == null) {
                     name = methodName;
+                } else {
+                    name = fieldName;
                 }
                 configurables[i].addAttribute(new Attribute("name", name)); // Add the type to avoid configure checking
             }
@@ -101,35 +100,43 @@
             String value = configurables[i].getAttribute("value");
 
             // Detect the type of the property
-            ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+            PojoMetadata manipulation = getFactory().getPojoMetadata();
             String type = null;
-            if (fieldName != null) {
-                FieldMetadata fm = manipulation.getField(fieldName);
-                if (fm == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation"); }
-                type = fm.getFieldType();
-                configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
-            } else {
-                MethodMetadata[] mm = manipulation.getMethods(methodName);
-                if (mm.length != 0) {
-                    if (mm[0].getMethodArguments().length != 1) {
-                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
-                    }
-                    if (type != null && !type.equals(mm[0].getMethodArguments()[0])) {
-                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + mm[0].getMethodArguments()[0] + ") are not the same.");
-                    }
-                    type = mm[0].getMethodArguments()[0];
-                    configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
-                } else {
+            if (fieldName == null) {
+                MethodMetadata[] method = manipulation.getMethods(methodName);
+                if (method.length == 0) {
                     type = configurables[i].getAttribute("type");
                     if (type == null) {
                         throw new ConfigurationException("Malformed property : The type of the property cannot be discovered, please add a 'type' attribute");
                     }
+                } else {
+                    if (method[0].getMethodArguments().length != 1) {
+                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
+                    }
+                    if (type != null && !type.equals(method[0].getMethodArguments()[0])) {
+                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the method type (" + method[0].getMethodArguments()[0] + ") are not the same.");
+                    }
+                    type = method[0].getMethodArguments()[0];
+                    configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
                 }
-            }
-            if (value != null) {
-                cd.addProperty(new PropertyDescription(name, type, value));
             } else {
-                cd.addProperty(new PropertyDescription(name, type, null));
+                FieldMetadata field = manipulation.getField(fieldName);
+                if (field == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation"); }
+                type = field.getFieldType();
+                configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
+            }
+            
+            // Is the property set to immutable
+            boolean immutable = false;
+            String imm = configurables[i].getAttribute("immutable");
+            if (imm != null && imm.equalsIgnoreCase("true")) {
+                immutable = true;
+            }
+            
+            if (value == null) {
+                desc.addProperty(new PropertyDescription(name, type, null, false)); // Cannot be immutable if we have no value.
+            } else {
+                desc.addProperty(new PropertyDescription(name, type, value, immutable));
             }
         }
     }
@@ -145,7 +152,7 @@
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
         // Store the component manager
-        m_configurableProperties = new ConfigurableProperty[0];
+        m_configurableProperties = new Property[0];
 
         // Build the map
         Element[] confs = metadata.getElements("Properties", "");
@@ -160,43 +167,32 @@
             m_toPropagate = configuration;
         }
 
-        List ff = new ArrayList();
-
-        for (int i = 0; i < configurables.length; i++) {
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
             String fieldName = configurables[i].getAttribute("field");
             String methodName = configurables[i].getAttribute("method");
 
             String name = configurables[i].getAttribute("name"); // The initialize method has fixed the property name.
             String value = configurables[i].getAttribute("value");
 
-            if (configuration.get(name) != null && configuration.get(name) instanceof String) {
-                value = (String) configuration.get(name);
-            } else {
-                if (fieldName != null && configuration.get(fieldName) != null && configuration.get(fieldName) instanceof String) {
-                    value = (String) configuration.get(fieldName);
-                }
-            }
-
             String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name.
             
-            if (fieldName != null) {
-                FieldMetadata fm = new FieldMetadata(fieldName, type);
-                ff.add(fm);
-            }
-            
-            ConfigurableProperty cp = new ConfigurableProperty(name, fieldName, methodName, value, type, this);
-            addProperty(cp);
+            Property prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
+            addProperty(prop);
 
             // Check if the instance configuration contains value for the current property :
-            if (configuration.get(name) != null && !(configuration.get(name) instanceof String)) {
-                cp.setValue(configuration.get(name));
-            } else {
-                if (fieldName != null && configuration.get(fieldName) != null && !(configuration.get(fieldName) instanceof String)) {
-                    cp.setValue(configuration.get(fieldName));
+            if (configuration.get(name) == null) {
+                if (fieldName != null && configuration.get(fieldName) != null) {
+                    prop.setValue(configuration.get(fieldName));
                 }
+            } else {
+                prop.setValue(configuration.get(name));
+            }
+            
+            if (fieldName != null) {
+                FieldMetadata field = new FieldMetadata(fieldName, type);
+                getInstanceManager().register(field, prop);
             }
         }
-        getInstanceManager().register(this, (FieldMetadata[]) ff.toArray(new FieldMetadata[ff.size()]), null);
     }
 
     /**
@@ -205,6 +201,7 @@
       * @see org.apache.felix.ipojo.Handler#stop()
       */
     public void stop() {
+        // Nothing to do.
     }
 
     /**
@@ -214,7 +211,7 @@
      */
     public void start() {
         // Get the provided service handler :
-        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":provides");
+        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":provides");
 
         // Propagation
         if (m_isConfigurable) {
@@ -225,45 +222,47 @@
         }
     }
 
-    /**
-     * Setter Callback Method.
-     * Check if the modified field is a configurable property to update the value.
-     * @param fieldName : field name
-     * @param value : new value
-     * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
-     */
-    public void setterCallback(String fieldName, Object value) {
-        // Verify that the field name correspond to a configurable property
-        for (int i = 0; i < m_configurableProperties.length; i++) {
-            ConfigurableProperty cp = m_configurableProperties[i];
-            if (cp.hasField() && cp.getField().equals(fieldName)) {
-                // Check if the value has changed
-                if (cp.getValue() == null || !cp.getValue().equals(value)) {
-                    cp.setValue(value); // Change the value
-                }
-            }
-        }
-        // Else do nothing
-    }
-
-    /**
-     * Getter Callback Method.
-     * Check if the field is a configurable property to push the stored value.
-     * @param fieldName : field name
-     * @param value : value pushed by the previous handler
-     * @return the stored value or the previous value.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String,
-     * java.lang.Object)
-     */
-    public Object getterCallback(String fieldName, Object value) {
-        // Check if the field is a configurable property
-        for (int i = 0; i < m_configurableProperties.length; i++) {
-            if (fieldName.equals(m_configurableProperties[i].getField())) { 
-                return m_configurableProperties[i].getValue(); 
-            }
-        }
-        return value;
-    }
+//    /**
+//     * Setter Callback Method.
+//     * Check if the modified field is a configurable property to update the value.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : field name
+//     * @param value : new value
+//     * @see org.apache.felix.ipojo.Handler#onSet(Object, java.lang.String, java.lang.Object)
+//     */
+//    public void onSet(Object pojo, String fieldName, Object value) {
+//        // Verify that the field name correspond to a configurable property
+//        for (int i = 0; i < m_configurableProperties.length; i++) {
+//            Property prop = m_configurableProperties[i];
+//            if (prop.hasField() && prop.getField().equals(fieldName)) {
+//                // Check if the value has changed
+//                if (prop.getValue() == null || !prop.getValue().equals(value)) {
+//                    prop.setValue(value); // Change the value
+//                }
+//            }
+//        }
+//        // Else do nothing
+//    }
+//
+//    /**
+//     * Getter Callback Method.
+//     * Check if the field is a configurable property to push the stored value.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : field name
+//     * @param value : value pushed by the previous handler
+//     * @return the stored value or the previous value.
+//     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+//     * java.lang.String, java.lang.Object)
+//     */
+//    public Object onGet(Object pojo, String fieldName, Object value) {
+//        // Check if the field is a configurable property
+//        for (int i = 0; i < m_configurableProperties.length; i++) {
+//            if (fieldName.equals(m_configurableProperties[i].getField())) { 
+//                return m_configurableProperties[i].getValue(); 
+//            }
+//        }
+//        return value;
+//    }
 
     /**
      * Handler state changed.
@@ -284,20 +283,20 @@
     /**
      * Add the given property metadata to the property metadata list.
      * 
-     * @param p : property metadata to add
+     * @param prop : property metadata to add
      */
-    protected void addProperty(ConfigurableProperty p) {
+    protected void addProperty(Property prop) {
         for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName().equals(p.getName())) { return; }
+            if (m_configurableProperties[i].getName().equals(prop.getName())) { return; }
         }
 
         if (m_configurableProperties.length > 0) {
-            ConfigurableProperty[] newProp = new ConfigurableProperty[m_configurableProperties.length + 1];
+            Property[] newProp = new Property[m_configurableProperties.length + 1];
             System.arraycopy(m_configurableProperties, 0, newProp, 0, m_configurableProperties.length);
-            newProp[m_configurableProperties.length] = p;
+            newProp[m_configurableProperties.length] = prop;
             m_configurableProperties = newProp;
         } else {
-            m_configurableProperties = new ConfigurableProperty[] { p };
+            m_configurableProperties = new Property[] { prop };
         }
     }
 
@@ -317,31 +316,31 @@
     /**
      * Reconfigure the component instance.
      * Check if the new configuration modify the current configuration.
-     * @param np : the new configuration
+     * @param configuration : the new configuration
      * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
      */
-    public void reconfigure(Dictionary np) {
+    public void reconfigure(Dictionary configuration) {
         Properties toPropagate = new Properties();
-        Enumeration keysEnumeration = np.keys();
+        Enumeration keysEnumeration = configuration.keys();
         while (keysEnumeration.hasMoreElements()) {
             String name = (String) keysEnumeration.nextElement();
-            Object value = np.get(name);
+            Object value = configuration.get(name);
             boolean found = false;
             // Check if the name is a configurable property
-            for (int i = 0; !found && i < m_configurableProperties.length; i++) {
+            for (int i = 0; i < m_configurableProperties.length; i++) {
                 if (m_configurableProperties[i].getName().equals(name)) {
                     // Check if the value has changed
                     if (m_configurableProperties[i].getValue() == null || !m_configurableProperties[i].getValue().equals(value)) {
                         if (m_configurableProperties[i].hasField()) {
-                            getInstanceManager().setterCallback(m_configurableProperties[i].getField(), value); // dispatch that the value has changed
+                            getInstanceManager().onSet(null, m_configurableProperties[i].getField(), value); // dispatch that the value has changed
                         }
                         if (m_configurableProperties[i].hasMethod()) {
                             m_configurableProperties[i].setValue(value);
-                            m_configurableProperties[i].invoke();
+                            m_configurableProperties[i].invoke(null); // Call on all created pojo objects.
                         }
                     }
                     found = true;
-                    // Else do nothing
+                    break;
                 }
             }
             if (!found) {
@@ -366,9 +365,9 @@
      * Handler createInstance method.
      * This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
-    public void objectCreated(Object instance) {
+    public void onCreation(Object instance) {
         for (int i = 0; i < m_configurableProperties.length; i++) {
             if (m_configurableProperties[i].hasMethod()) {
                 m_configurableProperties[i].invoke(instance);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
index 7258e23..9b3c0e3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -20,62 +20,28 @@
 
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.FieldInterceptor;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.MethodInterceptor;
 import org.apache.felix.ipojo.Nullable;
 import org.apache.felix.ipojo.PolicyServiceContext;
-import org.apache.felix.ipojo.ServiceContext;
-import org.apache.felix.ipojo.composite.CompositeServiceContext;
-import org.apache.felix.ipojo.util.Logger;
-import org.apache.felix.ipojo.util.ServiceReferenceRankingComparator;
-import org.apache.felix.ipojo.util.Tracker;
-import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.apache.felix.ipojo.handlers.dependency.ServiceUsage.Usage;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * Represent a service dependency of the component instance.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class Dependency implements TrackerCustomizer {
-
-    /**
-     * Dependency State : RESOLVED.
-     */
-    public static final int RESOLVED = 1;
-
-    /**
-     * Dependency State : UNRESOLVED.
-     */
-    public static final int UNRESOLVED = 2;
-    
-    /**
-     * Dependency State : BROKEN.
-     * Broken means that a used service disappears for static dependency.
-     */
-    public static final int BROKEN = 3;
-    
-    /**
-     * Dynamic Binding Policy (default).
-     */
-    public static final int DYNAMIC_POLICY = 0;
-
-    /**
-     * Dynamic Priority Binding Policy.
-     */
-    public static final int DYNAMIC_PRIORITY_POLICY = 1;
-    
-    /**
-     * Static Binding Policy.
-     */
-    public static final int STATIC_POLICY = 2;
+public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor {
 
     /**
      * Reference on the Dependency Handler.
@@ -90,144 +56,88 @@
     /**
      * List of dependency callback.
      */
-    private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+    private DependencyCallback[] m_callbacks;
 
     /**
-     * Service Specification required by the dependency.
-     */
-    private String m_specification;
-    
-    /**
-     * Dependency ID (declared ID, if not declare use the specification).
-     */
-    private String m_id;
-
-    /**
-     * Is the dependency a multiple dependency ?
-     */
-    private boolean m_isAggregate = false;
-
-    /**
-     * Is the Dependency an optional dependency ?
-     */
-    private boolean m_isOptional = false;
-
-    /**
-     * LDAP Filter of the Dependency (String form).
-     */
-    private String m_strFilter;
-    
-    /**
      * Is the dependency a service level dependency.
      */
-    private boolean m_isServiceLevelRequirement = false;
-    
-    /**
-     * Resolution policy.
-     */
-    private int m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL; 
+    private boolean m_isServiceLevelRequirement;
 
     /**
-     * Array of service references.
-     * m_ref : Array
+     * Is the provider set frozen ?
      */
-    private List m_references = new ArrayList();
-    
-    /**
-     * Array of service reference containing used service references. 
-     */
-    private List m_usedReferences = new ArrayList();
+    private boolean m_isFrozen;
 
     /**
-     * State of the dependency. 0 : stopped, 1 : valid, 2 : invalid. 
-     * m_state : int
+     * Is the dependency started ?
      */
-    private int m_state;
+    private boolean m_isStarted;
 
     /**
-     * Class of the dependency. 
-     * Useful to create in the case of multiple dependency
-     */
-    private Class m_clazz;
-
-    /**
-     * LDAP Filter of the dependency.
-     */
-    private Filter m_filter;
-    
-    /**
-     * Service Context in which resolving the dependency.
-     */
-    private ServiceContext m_serviceContext;
-    
-    /**
      * Thread Local.
      */
-    private ServiceUsage m_usage = new ServiceUsage();
+    private ServiceUsage m_usage;
 
     /**
-     * Service Tracker.
-     */
-    private Tracker m_tracker;
-    
-    /**
-     * IS the instance activated ? 
-     */
-    private boolean m_activated = false;
-    
-    /**
-     * Binding Policy.
-     */
-    private int m_bindingPolicy;
-    
-    /**
      * Nullable object.
      */
     private Object m_nullable;
-    
+
     /**
      * Default-Implementation.
      */
     private String m_di;
 
     /**
+     * Id of the dependency.
+     */
+    private String m_id;
+
+    /**
      * Dependency constructor. After the creation the dependency is not started.
      * 
-     * @param dh : the dependency handler managing this dependency
+     * @param handler : the dependency handler managing this dependency
      * @param field : field of the dependency
      * @param spec : required specification
      * @param filter : LDAP filter of the dependency
      * @param isOptional : is the dependency an optional dependency ?
      * @param isAggregate : is the dependency an aggregate dependency
-     * @param id : id of the dependency, may be null
+     * @param identity : id of the dependency, may be null
+     * @param context : bundle context (or service context) to use.
      * @param policy : resolution policy
-     * @param bindingPolicy : binding policy
-     * @param di : default-implementation class
+     * @param cmp : comparator to sort references
+     * @param defaultImplem : default-implementation class
      */
-    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy, int bindingPolicy, String di) {
-        m_handler = dh;
-        m_field = field;
-        m_specification = spec;
-        m_isOptional = isOptional;
-        m_di = di;
-       
-        m_strFilter = filter;
-        m_isAggregate = isAggregate;
-        if (m_id == null) {
-            m_id = m_specification;
+    public Dependency(DependencyHandler handler, String field, Class spec, Filter filter, boolean isOptional, boolean isAggregate, String identity, BundleContext context, int policy, Comparator cmp, String defaultImplem) {
+        super(spec, isAggregate, isOptional, filter, cmp, policy, context, handler);
+        m_handler = handler;
+        if (field != null) {
+            m_field = field;
+            m_usage = new ServiceUsage();
+        }
+        m_di = defaultImplem;
+
+        if (identity == null) {
+            if (spec != null) {
+                m_id = spec.getName();
+            }
         } else {
-            m_id = id;
-        }
-        if (policy != -1) {
-            m_policy = policy;
-        }
-        
-        m_bindingPolicy = bindingPolicy;
-        
-        // Fix the policy according to the level
-        if ((m_policy == PolicyServiceContext.LOCAL_AND_GLOBAL || m_policy == PolicyServiceContext.LOCAL) && ! ((((IPojoContext) m_handler.getInstanceManager().getContext()).getServiceContext()) instanceof CompositeServiceContext)) {
-            // We are not in a composite : BOTH | STRICT => GLOBAL
-            m_policy = PolicyServiceContext.GLOBAL;
+            m_id = identity;
+        } 
+        // Else wait the setSpecification call.
+    }
+
+    /**
+     * Set the specification of the current dependency.
+     * In order to store the id of the dependency, this
+     * method is override.
+     * @param spec : request service Class
+     * @see org.apache.felix.ipojo.util.DependencyModel#setSpecification(java.lang.Class)
+     */
+    public void setSpecification(Class spec) {
+        super.setSpecification(spec);
+        if (m_id == null) {
+            m_id = spec.getName();
         }
     }
 
@@ -235,122 +145,76 @@
         return m_field;
     }
 
-
-    public String getSpecification() {
-        return m_specification;
-    }
-
-
-    public boolean isOptional() {
-        return m_isOptional;
-    }
-
-
-    public boolean isAggregate() {
-        return m_isAggregate;
-    }
-
-    /**
-     * Set the dependency to aggregate.
-     */
-    protected void setAggregate() {
-        m_isAggregate = true;
-    }
-    
-    /**
-     * Activate the dependency.
-     * For static policy it freezes the service reference set.
-     */
-    void activate() {
-        if (m_bindingPolicy == STATIC_POLICY) {
-            m_activated = true;
-        }
-    }
-
-    /**
-     * Set the tracked specification for this dependency.
-     * @param spec : the tracked specification (interface name)
-     */
-    protected void setSpecification(String spec) {
-        m_specification = spec;
-    }
-
     /**
      * Add a callback to the dependency.
-     * @param cb : callback to add
+     * @param callback : callback to add
      */
-    protected void addDependencyCallback(DependencyCallback cb) {
-        if (m_callbacks.length > 0) {
+    protected void addDependencyCallback(DependencyCallback callback) {
+        if (m_callbacks == null) {
+            m_callbacks = new DependencyCallback[] { callback };
+        } else {
             DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
             System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
-            newCallbacks[m_callbacks.length] = cb;
+            newCallbacks[m_callbacks.length] = callback;
             m_callbacks = newCallbacks;
-        } else {
-            m_callbacks = new DependencyCallback[] { cb };
         }
     }
 
+    /**
+     * Stop the current dependency.
+     * @see org.apache.felix.ipojo.util.DependencyModel#stop()
+     */
+    public void stop() {
+        m_isStarted = false;
+        super.stop();
+    }
 
     /**
      * Get the string form of the filter.
      * @return : the string form of the filter.
      */
-    public String getFilter() {
-        if (m_strFilter == null) { return ""; }
-        return m_strFilter;
+    public String getStringFilter() {
+        return getFilter().toString();
     }
 
-
     public DependencyHandler getHandler() {
         return m_handler;
     }
 
-    /**
-     * Build the Set [service reference] of used services.
-     * @return the used service.
-     */
-    public List getUsedServices() {
-        return m_usedReferences;
+    public synchronized boolean isFrozen() {
+        return m_isFrozen;
     }
 
     /**
-     * This method is called by the replaced code in the component
-     * implementation class. Construct the service object list is necessary.
-     * 
-     * @return null or a service object or a list of service object according to
-     * the dependency.
+     * Call the bind method.
+     * @param pojo : pojo instance on which calling the bind method.
      */
-    Object get() {
-        // Initialize the thread local object is not already touched.
-        if (m_usage.getObjects().isEmpty()) {
-            if (isAggregate()) {
-                synchronized (m_tracker) {
-                    for (int i = 0; i < m_references.size(); i++) {
-                        ServiceReference ref = (ServiceReference) m_references.get(i);
-                        m_usage.getReferences().add(ref);
-                        m_usage.getObjects().add(getService(ref));
-                    }
-                }
-            } else {
-                if (m_references.size() == 0) {
-                    if (m_nullable == null) {
-                        m_handler.log(Logger.WARNING, "[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + m_specification);
-                        return null;
-                    }
-                    m_usage.getObjects().add(m_nullable);
-                } else {
-                    ServiceReference ref = (ServiceReference) m_references.get(0);
-                    m_usage.getReferences().add(ref); // Get the first one
-                    m_usage.getObjects().add(getService(ref));
-                }
-            }
-            m_usage.setStackLevel(1);
+    protected synchronized void onObjectCreation(Object pojo) {
+        if (!m_isStarted) { return; }
+
+        // We are notified of an instance creation, we have to freeze when the static policy is used
+        if (getBindingPolicy() == STATIC_BINDING_POLICY) {
+            m_isFrozen = true;
         }
 
-        if (m_isAggregate) { // Multiple dependency
-            return (Object[]) m_usage.getObjects().toArray((Object[]) Array.newInstance(m_clazz, m_usage.getObjects().size()));
-        } else {
-            return m_usage.getObjects().get(0);
+        // Check optional case : nullable object case : do not call bind on nullable object
+        if (isOptional() && getSize() == 0) { return; }
+
+        // Call bind callback.
+        for (int j = 0; m_callbacks != null && j < m_callbacks.length; j++) {
+            if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
+                if (isAggregate()) {
+                    ServiceReference[] refs = getServiceReferences();
+                    for (int i = 0; i < refs.length; i++) {
+                        invokeCallback(m_callbacks[j], refs[i], pojo);
+                    }
+                } else {
+                    ServiceReference ref = getServiceReference();
+                    if (ref != null) {
+                        invokeCallback(m_callbacks[j], ref, pojo);
+                    }
+                }
+            }
         }
     }
 
@@ -360,95 +224,38 @@
      */
     private void callUnbindMethod(ServiceReference ref) {
         if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
-            for (int i = 0; i < m_callbacks.length; i++) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
-                    try {
-                        m_callbacks[i].call(ref, getService(ref));
-                    } catch (NoSuchMethodException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().stop();
-                    }
+                    invokeCallback(m_callbacks[i], ref, null); // Call on each created pojo objects.
                 }
             }
         }
     }
 
     /**
-     * Get a service object for the given reference according to the resolving policy.
-     * @param ref : service reference
-     * @return the service object
+     * Helper method calling the given callback.
+     * @param callback : callback to call.
+     * @param ref : service reference.
+     * @param pojo : pojo on which calling the callback, if null call on each created pojo objects.
      */
-    private synchronized Object getService(ServiceReference ref) {
-        if (!m_usedReferences.contains(ref)) {
-            m_usedReferences.add(ref);
-        }
-        return m_tracker.getService(ref);
-    }
-    
-    /**
-     * Unget the given service reference according to the resolving policy.
-     * @param ref : service reference to unget
-     */
-    private void ungetService(ServiceReference ref) {
-        m_tracker.ungetService(ref);
-    }
-
-    /**
-     * Call the bind method.
-     * @param instance : instance on which calling the bind method.
-     */
-    protected synchronized void callBindMethod(Object instance) {
-        if (m_tracker == null) { return; }
-        // Check optional case : nullable object case : do not call bind on nullable object
-        if (m_isOptional && m_references.size() == 0) { return; }
-
-        if (m_isAggregate) {
-            for (int i = 0; i < m_references.size(); i++) {
-                ServiceReference ref = (ServiceReference) m_references.get(i);
-                for (int j = 0; j < m_callbacks.length; j++) {
-                    if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
-                        try {
-                            m_callbacks[j].callOnInstance(instance, ref, getService(ref));
-                        } catch (NoSuchMethodException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                            m_handler.getInstanceManager().stop();
-                        } catch (IllegalAccessException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                            m_handler.getInstanceManager().stop();
-                        } catch (InvocationTargetException e) {
-                            m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                            m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                        }
-                    }
-                }
+    private void invokeCallback(DependencyCallback callback, ServiceReference ref, Object pojo) {
+        try {
+            if (pojo == null) {
+                callback.call(ref, getService(ref));
+            } else {
+                callback.callOnInstance(pojo, ref, getService(ref));
             }
-        } else {
-            for (int j = 0; j < m_callbacks.length; j++) {
-                if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
-                    try {
-                        ServiceReference ref = (ServiceReference) m_references.get(0);
-                        if (ref != null) {
-                            m_callbacks[j].callOnInstance(instance, ref, getService(ref));
-                        }
-                    } catch (NoSuchMethodException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[j].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                    }
-                }
-            }
+        } catch (NoSuchMethodException e) {
+            m_handler.error("The method " + callback.getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().stop();
+        } catch (IllegalAccessException e) {
+            m_handler.error("The method " + callback.getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
+            m_handler.getInstanceManager().stop();
+        } catch (InvocationTargetException e) {
+            m_handler.error("The method " + callback.getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + " throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+            m_handler.getInstanceManager().stop();
         }
+
     }
 
     /**
@@ -459,112 +266,45 @@
         // call bind method :
         // if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
         if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
-            for (int i = 0; i < m_callbacks.length; i++) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
-                    try {
-                        m_callbacks[i].call(ref, getService(ref));
-                        ungetService(ref);
-                    } catch (NoSuchMethodException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " does not exist in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (IllegalAccessException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " is not accessible in the class " + m_handler.getInstanceManager().getClassName());
-                        m_handler.getInstanceManager().stop();
-                    } catch (InvocationTargetException e) {
-                        m_handler.log(Logger.ERROR, "The method " + m_callbacks[i].getMethodName() + " in the class " + m_handler.getInstanceManager().getClassName() + "throws an exception : " + e.getTargetException().getMessage());
-                        m_handler.getInstanceManager().setState(ComponentInstance.INVALID);
-                    }
+                    invokeCallback(m_callbacks[i], ref, null);
                 }
             }
         }
     }
-
+    
     /**
      * Start the dependency.
      */
-    public void start() {
-        
-        m_serviceContext = new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), m_policy);
-        
-        // Construct the filter with the objectclass + filter
-        String filter = "(objectClass=" + m_specification + ")";
-        if (m_strFilter != null) {
-            filter = "(&" + filter + m_strFilter + ")";
-        }
-        
-        try {
-            m_clazz = m_handler.getInstanceManager().getContext().getBundle().loadClass(m_specification);
-        } catch (ClassNotFoundException e) {
-            m_handler.log(Logger.ERROR, "Cannot load the interface class for the dependency " + m_field + " [" + m_specification + "]");
-        }
-        
-        if (m_isOptional) {
-            if (m_di != null) {
-                try {
-                    Class c = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
-                    m_nullable = c.newInstance();
-                } catch (IllegalAccessException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                } catch (InstantiationException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                } catch (ClassNotFoundException e) {
-                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + m_di + " : " + e.getMessage());
-                }
+    public void start() {        
+        if (isOptional() && !isAggregate()) {
+            if (m_di == null) {
+                // To load the proxy we use the POJO class loader. Indeed, this classloader imports iPOJO (so can access to Nullable) and has access to the service specification.
+                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] { getSpecification(), Nullable.class }, new NullableObject()); // NOPMD
             } else {
-                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] {m_clazz, Nullable.class}, new NullableObject());
+                try {
+                    Class clazz = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
+                    m_nullable = clazz.newInstance();
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                }
             }
         }
 
-        m_state = UNRESOLVED;
+        super.start();
 
-        try {
-            m_filter = m_handler.getInstanceManager().getContext().createFilter(filter); // Store the filter
-        } catch (InvalidSyntaxException e1) {
-            m_handler.log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] A filter is malformed : " + filter + " - " + e1.getMessage());
-            m_handler.getInstanceManager().stop();
-        }  
-        m_tracker = new Tracker(m_serviceContext, m_filter, this);
-        m_tracker.open();
-        if (m_tracker.size() == 0 && !m_isOptional) {
-            m_state = UNRESOLVED;
-        } else {
-            m_state = RESOLVED;
-        }
-    }
-
-    /**
-     * Stop the dependency.
-     */
-    public void stop() {
-        if (m_tracker != null) {
-            m_tracker.close(); // Will unget all used reference.
-            m_tracker = null;
+        if (getBindingPolicy() == STATIC_BINDING_POLICY && m_handler.getInstanceManager().getPojoObjects() != null) {
+            m_isFrozen = true;
         }
 
-        m_state = UNRESOLVED;
-
-        m_activated = false;
-        m_references.clear();
-        m_usedReferences.clear();
-        m_clazz = null;
+        m_isStarted = true;
     }
 
-    /**
-     * Return the state of the dependency.
-     * @return the state of the dependency (1 : valid, 2 : invalid)
-     */
-    public int getState() {
-        return m_state;
-    }
-
-    /**
-     * Return the list of used service reference.
-     * @return the service reference list.
-     */
-    public List getServiceReferences() {
-        return m_references;
-    }
-    
     protected DependencyCallback[] getCallbacks() {
         return m_callbacks;
     }
@@ -572,136 +312,183 @@
     /**
      * Set that this dependency is a service level dependency.
      * This forces the scoping policy to be STRICT. 
-     * @param b
      */
     public void setServiceLevelDependency() {
         m_isServiceLevelRequirement = true;
-        m_policy = PolicyServiceContext.LOCAL;
+        setBundleContext(new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), PolicyServiceContext.LOCAL));
     }
 
     public String getId() {
         return m_id;
     }
-    
+
     public boolean isServiceLevelRequirement() {
         return m_isServiceLevelRequirement;
     }
 
-    /**
-     * Method called when a thread enters in a method.
-     * @param method : method id.
-     */
-    public void entry(String method) {
-        if (! m_usage.getObjects().isEmpty()) {
-            int level = m_usage.getStackLevel();
-            m_usage.setStackLevel(level++);
-        }
-    }
-    
-    /**
-     * Method called when a thread exits a method.
-     * @param method : the method id.
-     */
-    public void exit(String method) {
-        if (! m_usage.getObjects().isEmpty()) {
-            int level = m_usage.getStackLevel();
-            level = level - 1;
-            if (level == 0) {
-                // Exit the method flow => Release all object
-                m_usage.getObjects().clear();
-                List refs = m_usage.getReferences();
-                refs.clear();
-            }
-        }
-    }
 
-   /**
-    * A new service is detected. This method check the reference against the stored filter.
-    * @param ref : new service reference.
-    * @return the service object, null is the service object is rejected.
-    * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
-    */
-    public boolean addingService(ServiceReference ref) {
-        if (! m_activated) {
-            return true;
-        }
-        return false;
-    }
-    
     /**
-     * A new service reference has been added in the tracker.
-     * Call the bind method if needed, and check the dependency context.
-     * @param reference : added reference.
-     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     * A new service has to be injected.
+     * @param reference : the new matching service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
      */
-    public void addedService(ServiceReference reference) {
-        m_references.add(reference);
-        if (m_bindingPolicy == DYNAMIC_PRIORITY_POLICY) {
-            Collections.sort(m_references, new ServiceReferenceRankingComparator());
-        }
-        m_state = RESOLVED;
-        if (m_isAggregate || m_references.size() == 1) {
-            callBindMethod(reference);
-        }
-        
-        m_handler.checkContext();
+    public void onServiceArrival(ServiceReference reference) {
+        callBindMethod(reference);
+        //The method is only called when a new service arrives, or when the used one is replaced.
     }
 
     /**
-     * A used service is modified.
-     * @param ref : modified reference
-     * @param arg1 : service object (returned when added) 
-     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     * A used (already injected) service disappears.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
      */
-    public void modifiedService(ServiceReference ref, Object arg1) { }
+    public void onServiceDeparture(ServiceReference ref) {
+        callUnbindMethod(ref);
+    }
 
     /**
-     * A used service disappears.
-     * @param ref : implicated service.
-     * @param arg1 : service object.
-     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     * The dependency has been reconfigured.
+     * @param departs : service no more matching.
+     * @param arrivals : new services
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
      */
-    public void removedService(ServiceReference ref, Object arg1) {
-        // Call unbind method
-        boolean hasChanged = false;
-        m_references.remove(ref);
-        if (m_usedReferences.remove(ref)) {
-            callUnbindMethod(ref);
-            
-            // Null the ref in the instance manager map
-            if (m_field != null) {
-                m_handler.getInstanceManager().setterCallback(m_field, null);
-            }
-            
-            // Unget the service reference
-            ungetService(ref);
-            hasChanged = true;
-        }
-        
-        if (m_bindingPolicy == STATIC_POLICY) {
-            if (hasChanged && m_activated) {
-                m_state = BROKEN;
-            }
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        throw new UnsupportedOperationException("Dependency set change is not yet supported");
+    }
+
+    /**
+     * Get the used service references list.
+     * @return the used service reference or null if no service reference are available.
+     */
+    public List getServiceReferencesAsList() {
+        ServiceReference[] refs = super.getServiceReferences();
+        if (refs == null) {
+            return null;
         } else {
-            // Is the state valid or invalid, the reference is already removed
-            if (m_references.size() == 0 && !m_isOptional) {
-                m_state = UNRESOLVED;
-            } else {
-                m_state = RESOLVED;
-            }
-            
-            // Is there any change ?
-            if (!m_isAggregate) {
-                if (hasChanged) { // The used reference has been removed
-                    if (m_references.size() != 0) {
-                        callBindMethod(m_references.get(0));
+            return Arrays.asList(refs);
+        }
+    }
+
+    /**
+     * This method is called by the replaced code in the component
+     * implementation class. Construct the service object list is necessary.
+     * @param pojo : POJO object.
+     * @param fieldName : field
+     * @param value : last value.
+     * @return the service object or a nullable / default implementation if defined.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+     // Initialize the thread local object is not already touched.
+        Usage usage = (Usage) m_usage.get();
+        if (usage.m_stack == 0) { // uninitialized usage.
+            ServiceReference[] refs = super.getServiceReferences();
+            if (isAggregate()) { // If we are aggregate we get the objects.
+                if (refs == null) {
+                    usage.m_objects = (Object[]) Array.newInstance(getSpecification(), 0); // Create an empty array.
+                } else {
+                   // Use a reflective construction to avoid class cast exception. This method allow to set the component type.
+                    usage.m_objects = (Object[]) Array.newInstance(getSpecification(), refs.length); 
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        ServiceReference ref = refs[i];
+                        usage.m_objects[i] = getService(ref);
                     }
                 }
+            } else { // We are singular.
+                // Use a reflective construction to avoid class cast exception. This method allow to set the component type.
+                usage.m_objects = (Object[]) Array.newInstance(getSpecification(), 1);
+                if (refs == null) {
+                    if (m_nullable == null) {
+                        m_handler.warn("[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + getSpecification().getName());
+                        return null;
+                    }
+                    usage.m_objects[0] = m_nullable;
+                } else {
+                    ServiceReference ref = getServiceReference();
+                    usage.m_objects[0] = getService(ref);
+                }
+            }
+            usage.inc(); // Start the tracking, so fix the stack level to 1
+            m_usage.set(usage);
+        }
+
+        if (isAggregate()) { // Multiple dependency
+            return usage.m_objects;
+        } else {
+            return usage.m_objects[0];
+        }
+    }
+
+    /**
+     * The field was set.
+     * This method should not be call if the POJO is written correctly.
+     * @param pojo : POJO object
+     * @param fieldName : field name
+     * @param value : set value.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Nothing to do.
+    }
+
+    /**
+     * A POJO method will be invoked.
+     * @param pojo : Pojo object
+     * @param method : called method
+     * @param args : arguments
+     * @see org.apache.felix.ipojo.MethodInterceptor#onEntry(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public void onEntry(Object pojo, Method method, Object[] args) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            if (usage.m_stack > 0) {
+                usage.inc();
+                m_usage.set(usage); // Set the Thread local as value has been modified
+            }
+        }
+    }
+
+    /**
+     * A POJO method has thrown an error.
+     * This method does nothing and wait for the finally.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param throwable : thrown error
+     * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
+     */
+    public void onError(Object pojo, Method method, Throwable throwable) {
+        // Nothing to do  : wait onFinally
+    }
+
+    /**
+     * A POJO method has returned.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param returnedObj : returned object (null for void method)
+     * @see org.apache.felix.ipojo.MethodInterceptor#onExit(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
+     */
+    public void onExit(Object pojo, Method method, Object returnedObj) {
+        // Nothing to do  : wait onFinally
+        
+    }
+
+    /**
+     * A POJO method is finished.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @see org.apache.felix.ipojo.MethodInterceptor#onFinally(java.lang.Object, java.lang.reflect.Method)
+     */
+    public void onFinally(Object pojo, Method method) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            if (usage.m_stack > 0) {
+                if (usage.dec()) {
+                    // Exit the method flow => Release all objects
+                    usage.clear();
+                    m_usage.set(usage); // Set the Thread local as value has been modified
+                }
             }
         }
-
-        m_handler.checkContext();
-        return;
     }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
index cb47c30..ad476c6 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -22,7 +22,6 @@
 import java.lang.reflect.Method;
 
 import org.apache.felix.ipojo.util.Callback;
-import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -42,7 +41,6 @@
      * Unbind method (called when a service disappears).
      */
     public static final int UNBIND = 1;
-    
 
     /**
      * Is the method a bind method or an unbind method ?
@@ -104,20 +102,25 @@
     protected void searchMethod() {
         if (m_argument != null) {
             Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getDeclaredMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
+            for (int i = 0; i < methods.length; i++) {
                 // First check the method name
                 if (methods[i].getName().equals(m_method)) {
                     // Check arguments
                     Class[] clazzes = methods[i].getParameterTypes();
-                    if (clazzes.length == m_argument.length) { // Test size to avoid useless loop
-                        boolean ok = true;
-                        for (int j = 0; ok && j < m_argument.length; j++) {
-                            if (!m_argument[j].equals(clazzes[j].getName())) {
-                                ok = false;
+                    if (clazzes.length == m_argument.length) { // Test size to avoid useless loop // NOPMD
+                        int argIndex = 0;
+                        for (; argIndex < m_argument.length; argIndex++) {
+                            if (!m_argument[argIndex].equals(clazzes[argIndex].getName())) {
+                                break;
                             }
                         }
-                        if (ok) {
+                        if (argIndex == m_argument.length) { // If the array was completely read.
                             m_methodObj = methods[i]; // It is the looked method.
+                            if (! m_methodObj.isAccessible()) { 
+                                // If not accessible, try to set the accessibility.
+                                m_methodObj.setAccessible(true);
+                            }
+                            return;
                         }
                     }
 
@@ -125,51 +128,64 @@
             }
         }
         
-        if (m_methodObj == null) { //look at parent classes
-            Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
-                // First check the method name
-                if (methods[i].getName().equals(m_method)) {
-                    // Check arguments
-                    Class[] clazzes = methods[i].getParameterTypes();
-                    switch(clazzes.length) {
-                        case 0 : 
-                            // Callback with no arguments.
-                            m_methodObj = methods[i];
-                            m_argument = new String[0];
-                            break;
-                        case 1 :
-                            if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
-                                // Callback with a service reference.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {ServiceReference.class.getName()};
-                                break;
-                            }
-                            if (clazzes[0].getName().equals(m_dependency.getSpecification())) {
-                                // Callback with the service object.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {m_dependency.getSpecification()};
-                                break;
-                            }
-                        case 2 : 
-                            if (clazzes[0].getName().equals(m_dependency.getSpecification())  && clazzes[1].getName().equals(ServiceReference.class.getName())) {
-                                // Callback with two arguments.
-                                m_methodObj = methods[i];
-                                m_argument = new String[] {m_dependency.getSpecification(), ServiceReference.class.getName()};
-                            }
-                            break;
-                        default :
-                            break;
-                    }
-                }
-            }
-        }
+        // Not found => Try parent method.
+        searchParentMethod();
         
         if (m_methodObj == null) {
-            m_dependency.getHandler().log(Logger.ERROR, "The method " + m_method + " cannot be called : method not found");
+            // If not found, stop the instance (fatal error)
+            m_dependency.getHandler().error("The method " + m_method + " cannot be called : method not found");
             m_dependency.getHandler().getInstanceManager().stop();
         } else {
-            m_methodObj.setAccessible(true);
+            if (! m_methodObj.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
+        }
+    }
+    
+    /**
+     * Introspect parent class to find the method.
+     */
+    private void searchParentMethod() {
+        // look at parent classes
+        Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            // First check the method name
+            if (methods[i].getName().equals(m_method)) {
+                // Check arguments
+                Class[] clazzes = methods[i].getParameterTypes();
+                switch (clazzes.length) {
+                    case 0:
+                        // Callback with no arguments.
+                        m_methodObj = methods[i];
+                        m_argument = new String[0];
+                        return;
+                    case 1:
+                        if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with a service reference.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { ServiceReference.class.getName() };
+                            return;
+                        }
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName())) {
+                            // Callback with the service object.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName() };
+                            return;
+                        }
+                        break;
+                    case 2:
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with two arguments.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName(), ServiceReference.class.getName() };
+                            return;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
index f9dea1b..6c09bd5 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
@@ -79,7 +79,6 @@
         m_optional = optional;
         m_filter = filter;
         m_state = state;
-        m_serviceReferences = new ArrayList();
     }
 
     public boolean isMultiple() { return m_multiple; }
@@ -106,9 +105,9 @@
 
     /**
      * Set the service reference array.
-     * @param sr : the list of service reference
+     * @param refs : the list of service reference
      */
-    public void setServiceReferences(List sr) { m_serviceReferences = sr; }
+    public void setServiceReferences(List refs) { m_serviceReferences = refs; }
 
     /**
      * Get the used service set.
@@ -118,10 +117,10 @@
 
     /**
      * Set the usedServices.
-     * @param hm : the list of used service reference.
+     * @param usages : the list of used service reference.
      */
-    public void setUsedServices(List hm) {
-        m_usedServices = hm;
+    public void setUsedServices(List usages) {
+        m_usedServices = usages;
     }
 
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 433f0b1..5a0f4d8 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -18,27 +18,30 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Dictionary;
-import java.util.List;
 
-import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
 /**
  * The dependency handler manages a list of service dependencies.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class DependencyHandler extends PrimitiveHandler {
+public class DependencyHandler extends PrimitiveHandler implements DependencyStateListener {
 
     /**
      * List of dependencies of the component.
@@ -46,12 +49,6 @@
     private Dependency[] m_dependencies = new Dependency[0];
 
     /**
-     * State of the handler.
-     * Lifecycle controller.
-     */
-    private boolean m_state;
-
-    /**
      * Is the handler started.
      */
     private boolean m_started;
@@ -61,16 +58,18 @@
      * @param dep : the dependency to add
      */
     private void addDependency(Dependency dep) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            if (m_dependencies[i] == dep) { return; }
+        for (int i = 0; m_dependencies != null && i < m_dependencies.length; i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
         }
-        if (m_dependencies.length > 0) {
+        if (m_dependencies == null) {
+            m_dependencies = new Dependency[] { dep };
+        } else {
             Dependency[] newDep = new Dependency[m_dependencies.length + 1];
             System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
             newDep[m_dependencies.length] = dep;
             m_dependencies = newDep;
-        } else {
-            m_dependencies = new Dependency[] { dep };
         }
     }
 
@@ -83,36 +82,56 @@
     }
 
     /**
+     * Validate method. This method is invoked by an AbstractServiceDependency when this dependency becomes RESOLVED.
+     * @param dep : the dependency becoming RESOLVED.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#validate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void validate(DependencyModel dep) {
+        checkContext();
+    }
+
+    /**
+     * Invalidate method. This method is invoked by an AbstractServiceDependency when this dependency becomes UNRESOLVED or BROKEN.
+     * @param dep : the dependency becoming UNRESOLVED or BROKEN.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#invalidate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void invalidate(DependencyModel dep) {
+        setValidity(false);
+    }
+
+    /**
      * Check the validity of the dependencies.
      */
     protected void checkContext() {
-        if (! m_started) { return; }
+        if (!m_started) {
+            return;
+        }
         synchronized (m_dependencies) {
             // Store the initial state
-            boolean initialState = m_state;
+            boolean initialState = getValidity();
 
             boolean valid = true;
             for (int i = 0; i < m_dependencies.length; i++) {
                 Dependency dep = m_dependencies[i];
-                if (dep.getState() > Dependency.RESOLVED) { 
+                if (dep.getState() != Dependency.RESOLVED) {
                     valid = false;
                     break;
                 }
             }
-            
+
             // Check the component dependencies
             if (valid) {
                 // The dependencies are valid
                 if (!initialState) {
                     // There is a state change
-                    m_state = true;
+                    setValidity(true);
                 }
                 // Else do nothing, the component state stay VALID
             } else {
                 // The dependencies are not valid
                 if (initialState) {
                     // There is a state change
-                    m_state = false;
+                    setValidity(false);
                 }
                 // Else do nothing, the component state stay UNRESOLVED
             }
@@ -121,155 +140,197 @@
     }
 
     /**
-     * Check if the dependency given is valid in the sense that metadata are
-     * consistent.
+     * Check if the dependency given is valid in the sense that metadata are consistent.
      * @param dep : the dependency to check
      * @param manipulation : the component-type manipulation metadata
      * @return true if the dependency is valid
      * @throws ConfigurationException : the checked dependency is not correct
      */
-    private boolean checkDependency(Dependency dep, ManipulationMetadata manipulation) throws ConfigurationException {
+    private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
         // Check the internal type of dependency
         String field = dep.getField();
         DependencyCallback[] callbacks = dep.getCallbacks();
 
-        for (int i = 0; i < callbacks.length; i++) {
+        if (callbacks == null && field == null) {
+            throw new ConfigurationException("A service requirement requires at least callbacks or a field");
+        }
+
+        for (int i = 0; callbacks != null && i < callbacks.length; i++) {
             MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
-            if (mets.length != 0) {
+            if (mets.length == 0) {
+                info("A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
+            } else {
                 if (mets[0].getMethodArguments().length > 2) {
-                    throw new ConfigurationException("Requirement Callback : A requirement callback " + callbacks[i].getMethodName() + " must have 0 or 1 or 2 arguments");
+                    throw new ConfigurationException("Requirement Callback : A requirement callback "
+                            + callbacks[i].getMethodName()
+                            + " must have 0 or 1 or 2 arguments");
                 }
-                
+
                 callbacks[i].setArgument(mets[0].getMethodArguments());
+
                 if (mets[0].getMethodArguments().length == 1) {
                     if (!mets[0].getMethodArguments()[0].equals(ServiceReference.class.getName())) {
-                        if (dep.getSpecification() == null) {
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
+                        // The callback receives the service object.
+                        setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                     }
                 } else if (mets[0].getMethodArguments().length == 2) {
-                    // Check that the second arguments is a service reference
+                    // The callback receives service object, service reference. Check that the second argument is a service reference
                     if (!mets[0].getMethodArguments()[1].equals(ServiceReference.class.getName())) {
-                        String message = "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second arguments";
+                        String message =
+                                "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference as the second argument";
                         throw new ConfigurationException(message);
                     }
-                    if (dep.getSpecification() == null) {
-                        dep.setSpecification(mets[0].getMethodArguments()[0]);
-                    } else {
-                        if (!dep.getSpecification().equals(mets[0].getMethodArguments()[0])) {
-                            log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + mets[0].getMethodArguments()[0] + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                            dep.setSpecification(mets[0].getMethodArguments()[0]);
-                        }
-                    }
+                    setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
                 }
-            } else {
-                log(Logger.INFO, "A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation, try the super classes");
             }
 
         }
 
         if (field != null) {
-            FieldMetadata fm = manipulation.getField(field);
-            if (fm == null) {
-                throw new ConfigurationException("Requirement Callback : A requirement field " + field + " does not exist in the implementation class");
+            FieldMetadata meta = manipulation.getField(field);
+            if (meta == null) {
+                throw new ConfigurationException("Requirement Callback : A requirement field "
+                        + field
+                        + " does not exist in the implementation class");
             }
-            String type = fm.getFieldType();
+            String type = meta.getFieldType();
             if (type.endsWith("[]")) {
                 // Set the dependency to multiple
-                dep.setAggregate();
+                dep.setAggregate(true);
                 type = type.substring(0, type.length() - 2);
+            } else {
+                if (dep.isAggregate()) {
+                    throw new ConfigurationException("A required service is not correct : the field "
+                            + meta.getFieldName()
+                            + " must be an array to support aggregate injections");
+                }
             }
-
-            if (dep.getSpecification() == null) {
-                dep.setSpecification(type);
-            }
-
-            if (!dep.getSpecification().equals(type)) {
-                log(Logger.WARNING, "[DependencyHandler on " + getInstanceManager().getInstanceName() + "] The field type [" + type + "] and the needed service interface [" + dep.getSpecification() + "] are not the same");
-                dep.setSpecification(type);
-            }
+            setSpecification(dep, type, true); // Throw an exception if the filed type mismatch.
         }
 
-        //Check that all required info are set
+        // Check that all required info are set
         return dep.getSpecification() != null;
     }
 
     /**
+     * Check if we have to set the dependency specification with the given class name.
+     * @param dep : dependency to check
+     * @param className : class name
+     * @param error : set to true to throw an error if the set dependency specification and the given specification are different.
+     * @throws ConfigurationException : the specification class cannot be loaded correctly
+     */
+    private void setSpecification(Dependency dep, String className, boolean error) throws ConfigurationException {
+        // We have to set the dependency in two cases : either the dependency as no specification, or the specification is different from the given
+        // one
+        if (dep.getSpecification() == null || !dep.getSpecification().getName().equals(className)) {
+            if (dep.getSpecification() != null) {
+                if (error) {
+                    throw new ConfigurationException("A required service is not correct : the discoevered type ["
+                            + className
+                            + "] and the specified (or already discovered)  service interface ["
+                            + dep.getSpecification().getName()
+                            + "] are not the same");
+                } else {
+                    // If the specification is different, warn that we will overide it.
+                    warn("[DependencyHandler on "
+                            + getInstanceManager().getInstanceName()
+                            + "] The field type ["
+                            + className
+                            + "] and the needed service interface ["
+                            + dep.getSpecification()
+                            + "] are not the same");
+                }
+            }
+            try {
+                dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("The required service interface cannot be loaded : " + e.getMessage());
+            }
+        }
+    }
+
+    /**
      * Configure the handler.
      * @param componentMetadata : the component type metadata
      * @param configuration : the instance configuration
      * @throws ConfigurationException : one dependency metadata is not correct.
-     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element,
+     *      java.util.Dictionary)
      */
     public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
-        m_dependencies = new Dependency[0];
-
-        ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
-        List fl = new ArrayList();
+        // getPojoMetadata();
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
+        boolean atLeastOneField = false;
 
         // Create the dependency according to the component metadata
         Element[] deps = componentMetadata.getElements("Requires");
-
+        
         // Get instance filters.
         Dictionary filtersConfiguration = (Dictionary) configuration.get("requires.filters");
-        
-        for (int i = 0; i < deps.length; i++) {
+
+        for (int i = 0; deps != null && i < deps.length; i++) {
             // Create the dependency metadata
             String field = deps[i].getAttribute("field");
             String serviceSpecification = deps[i].getAttribute("interface");
             String filter = deps[i].getAttribute("filter");
             String opt = deps[i].getAttribute("optional");
             boolean optional = opt != null && opt.equalsIgnoreCase("true");
-            String di = deps[i].getAttribute("default-implementation");
-            
+            String defaultImplem = deps[i].getAttribute("default-implementation");
+
             String agg = deps[i].getAttribute("aggregate");
             boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
-            String id = deps[i].getAttribute("id");
+            String identitity = deps[i].getAttribute("id");
 
-            int scopePolicy = -1;
-            String scope = deps[i].getAttribute("scope"); 
+            String scope = deps[i].getAttribute("scope");
+            BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
             if (scope != null) {
-                if (scope.equalsIgnoreCase("global")) {
-                    scopePolicy = PolicyServiceContext.GLOBAL;
+                // If we are not in a composite, the policy is set to global.
+                if (scope.equalsIgnoreCase("global") || ((((IPojoContext) getInstanceManager().getContext()).getServiceContext()) == null)) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.GLOBAL);
                 } else if (scope.equalsIgnoreCase("composite")) {
-                    scopePolicy = PolicyServiceContext.LOCAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL);
                 } else if (scope.equalsIgnoreCase("composite+global")) {
-                    scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL_AND_GLOBAL);
                 }
             }
 
             // Get instance filter if available
-            if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
-                filter = (String) filtersConfiguration.get(id);
+            if (filtersConfiguration != null && identitity != null && filtersConfiguration.get(identitity) != null) {
+                filter = (String) filtersConfiguration.get(identitity);
             }
-            
-            
-            // Parse binding policy
-            int bindingPolicy = Dependency.DYNAMIC_POLICY;
-            String policy = deps[i].getAttribute("policy"); 
-            if (policy != null) {
-                if (policy.equalsIgnoreCase("static")) {
-                    bindingPolicy = Dependency.STATIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic")) {
-                    bindingPolicy = Dependency.DYNAMIC_POLICY;
-                } else if (policy.equalsIgnoreCase("dynamic-priority")) {
-                    bindingPolicy = Dependency.DYNAMIC_PRIORITY_POLICY;
+
+            Filter fil = null;
+            if (filter != null) {
+                try {
+                    fil = getInstanceManager().getContext().createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
                 }
             }
-            
-            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy, bindingPolicy, di);
+
+            Class spec = null;
+            if (serviceSpecification != null) {
+                spec = DependencyModel.loadSpecification(serviceSpecification, getInstanceManager().getContext());
+            }
+
+            int policy = DependencyModel.getPolicy(deps[i]);
+            Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
+            Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, identitity, context, policy, cmp, defaultImplem);
 
             // Look for dependency callback :
-            for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
-                if (!(deps[i].getElements("Callback", "")[j].containsAttribute("method") && deps[i].getElements("Callback", "")[j].containsAttribute("type"))) { 
-                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute"); 
+            Element[] cbs = deps[i].getElements("Callback");
+            for (int j = 0; cbs != null && j < cbs.length; j++) {
+                if (!cbs[j].containsAttribute("method") && cbs[j].containsAttribute("type")) {
+                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type attribute");
                 }
-                String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
-                String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+                String method = cbs[j].getAttribute("method");
+                String type = cbs[j].getAttribute("type");
                 int methodType = 0;
                 if ("bind".equalsIgnoreCase(type)) {
                     methodType = DependencyCallback.BIND;
@@ -277,74 +338,49 @@
                     methodType = DependencyCallback.UNBIND;
                 }
 
-                DependencyCallback dc = new DependencyCallback(dep, method, methodType);
-                dep.addDependencyCallback(dc);
+                DependencyCallback callback = new DependencyCallback(dep, method, methodType);
+                dep.addDependencyCallback(callback);
             }
 
             // Check the dependency :
             if (checkDependency(dep, manipulation)) {
                 addDependency(dep);
                 if (dep.getField() != null) {
-                    fl.add(manipulation.getField(dep.getField()));
+                    getInstanceManager().register(manipulation.getField(dep.getField()), dep);
+                    atLeastOneField = true;
                 }
             }
         }
 
-        if (deps.length > 0) {
-            getInstanceManager().register(this, (FieldMetadata[]) fl.toArray(new FieldMetadata[0]), manipulation.getMethods());
-        } else {
-            throw new ConfigurationException("No dependencies found in " + getInstanceManager().getInstanceName());
-        }
-    }
-
-    /**
-     * GetterCallback Method.
-     * @param fieldName : the field name.
-     * @param value : the value passed to the field (by the previous handler).
-     * @return the object that the dependency handler want to push.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
-     */
-    public Object getterCallback(String fieldName, Object value) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            String field = dep.getField();
-            if (field != null && field.equals(fieldName)) {
-                // The field name is a dependency, return the get
-                return dep.get();
-            }
-        }
-        // Else return the value
-        return value;
-    }
-
-    /**
-     * Method Entry callback.
-     * @param methodId : method Id.
-     * @see org.apache.felix.ipojo.Handler#entryCallback(java.lang.String)
-     */
-    public void entryCallback(String methodId) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.entry(methodId);
+        if (atLeastOneField) { // Does register only if we have fields
+            MethodMetadata[] methods = manipulation.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                for (int j = 0; j < m_dependencies.length; j++) {
+                    getInstanceManager().register(methods[i], m_dependencies[j]);
+                }
             }
         }
     }
 
-    /**
-     * Method Exit callback.
-     * @param methodId : method id.
-     * @param returnedObj : returned object.
-     * @see org.apache.felix.ipojo.Handler#exitCallback(java.lang.String, java.lang.Object)
-     */
-    public void exitCallback(String methodId, Object returnedObj) {
-        for (int i = 0; i < m_dependencies.length; i++) {
-            Dependency dep = m_dependencies[i];
-            if (dep.getField() != null) {
-                dep.exit(methodId);
-            }
-        }
-    }
+//    /**
+//     * GetterCallback Method.
+//     * @param pojo : the pojo object on which the field is accessed
+//     * @param fieldName : the field name.
+//     * @param value : the value passed to the field (by the previous handler).
+//     * @return the object that the dependency handler want to push.
+//     * @see org.apache.felix.ipojo.Handler#onGet(Object, java.lang.String, java.lang.Object)
+//     */
+//    public Object onGet(Object pojo, String fieldName, Object value) {
+//        for (int i = 0; i < m_dependencies.length; i++) {
+//            Dependency dep = m_dependencies[i];
+//            if (fieldName.equals(dep.getField())) {
+//                // The field name is a dependency, return the get
+//                return dep.get();
+//            }
+//        }
+//        // Else return the value
+//        return value;
+//    }
 
     /**
      * Handler start method.
@@ -358,6 +394,7 @@
         }
         // Check the state
         m_started = true;
+        setValidity(false);
         checkContext();
     }
 
@@ -373,27 +410,13 @@
     }
 
     /**
-     * Handler createInstance method.
-     * This method is override to allow delayed callback invocation.
+     * Handler createInstance method. This method is override to allow delayed callback invocation.
      * @param instance : the created object
-     * @see org.apache.felix.ipojo.Handler#objectCreated(java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
-    public void objectCreated(Object instance) {
+    public void onCreation(Object instance) {
         for (int i = 0; i < m_dependencies.length; i++) {
-            m_dependencies[i].callBindMethod(instance);
-        }
-    }
-    
-    /**
-     * The instance state changes. If the new state is valid, we need to activate dependencies.
-     * @param state : the new state
-     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
-     */
-    public void stateChanged(int state) {
-        if (state == ComponentInstance.VALID) {
-            for (int i = 0; i < m_dependencies.length; i++) {
-                m_dependencies[i].activate();
-            }
+            m_dependencies[i].onObjectCreation(instance);
         }
     }
 
@@ -407,10 +430,11 @@
         for (int j = 0; j < getDependencies().length; j++) {
             Dependency dep = getDependencies()[j];
             // Create & add the dependency description
-            DependencyDescription dd = new DependencyDescription(dep.getSpecification(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
-            dd.setServiceReferences(dep.getServiceReferences());
-            dd.setUsedServices(dep.getUsedServices());
-            dhd.addDependency(dd);
+            DependencyDescription desc =
+                    new DependencyDescription(dep.getSpecification().getName(), dep.isAggregate(), dep.isOptional(), dep.getFilter(), dep.getState());
+            desc.setServiceReferences(dep.getServiceReferencesAsList());
+            desc.setUsedServices(dep.getUsedServiceReferences());
+            dhd.addDependency(desc);
         }
         return dhd;
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
index 1615521..aaf5baa 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
@@ -42,10 +42,10 @@
 
     /**
      * Constructor.
-     * @param h : Handler.
+     * @param handler : Handler.
      */
-    public DependencyHandlerDescription(Handler h) {
-        super(h);
+    public DependencyHandlerDescription(Handler handler) {
+        super(handler);
     }
 
     /**
@@ -94,7 +94,7 @@
             Element dep = new Element("Requires", "");
             dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
             
-            if (!"".equals(m_dependencies[i].getFilter())) {
+            if (m_dependencies[i].getFilter() != null) {
                 dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
             }
             
@@ -112,16 +112,18 @@
             
             dep.addAttribute(new Attribute("State", state));
             List set = m_dependencies[i].getUsedServices();
-            Iterator it = set.iterator();
-            while (it.hasNext()) {
-                Element use = new Element("Uses", "");
-                ServiceReference ref = (ServiceReference) it.next();
-                use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
-                String in = (String) ref.getProperty("instance.name");
-                if (in != null) {
-                    use.addAttribute(new Attribute("instance.name", in));
+            if (set != null) {
+                Iterator iterator = set.iterator();
+                while (iterator.hasNext()) {
+                    Element use = new Element("Uses", "");
+                    ServiceReference ref = (ServiceReference) iterator.next();
+                    use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
+                    String instance = (String) ref.getProperty("instance.name");
+                    if (instance != null) {
+                        use.addAttribute(new Attribute("instance.name", instance));
+                    }
+                    dep.addElement(use);
                 }
-                dep.addElement(use);
             }
             
             deps.addElement(dep);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
index e0e4900..b11419f 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
@@ -26,41 +26,42 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

 public class NullableObject implements InvocationHandler {

-    

+

     /**

      * Default boolean value.

      */

     private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;

+

     /**

      * Default byte value.

      */

     private static final Byte DEFAULT_BYTE = new Byte((byte) 0);

-    

+

     /**

      * Default short value.

      */

     private static final Short DEFAULT_SHORT = new Short((short) 0);

-    

+

     /**

      * Default integer value.

      */

     private static final Integer DEFAULT_INT = new Integer(0);

-    

+

     /**

      * Default long value.

      */

     private static final Long DEFAULT_LONG = new Long(0);

-    

+

     /**

      * Default float value.

      */

     private static final Float DEFAULT_FLOAT = new Float(0.0f);

-    

+

     /**

      * Default double value.

      */

     private static final Double DEFAULT_DOUBLE = new Double(0.0);

-    

+

     /**

      * Invokes a method on this null object. The method will return a default

      * value without doing anything.

@@ -72,19 +73,19 @@
      */

     public Object invoke(Object proxy, Method method, Object[] args) {

         Class returnType = method.getReturnType();

-        if (returnType.equals(Boolean.TYPE)) {

+        if (Boolean.TYPE.equals(returnType)) {

             return DEFAULT_BOOLEAN;

-        } else if (returnType.equals(Byte.TYPE)) {

+        } else if (Byte.TYPE.equals(returnType)) {

             return DEFAULT_BYTE;

-        } else if (returnType.equals(Short.TYPE)) {

+        } else if (Short.TYPE.equals(returnType)) {

             return DEFAULT_SHORT;

-        } else if (returnType.equals(Integer.TYPE)) {

+        } else if (Integer.TYPE.equals(returnType)) {

             return DEFAULT_INT;

-        } else if (returnType.equals(Long.TYPE)) {

+        } else if (Long.TYPE.equals(returnType)) {

             return DEFAULT_LONG;

-        } else if (returnType.equals(Float.TYPE)) {

+        } else if (Float.TYPE.equals(returnType)) {

             return DEFAULT_FLOAT;

-        } else if (returnType.equals(Double.TYPE)) {

+        } else if (Double.TYPE.equals(returnType)) {

             return DEFAULT_DOUBLE;

         } else {

             return null;

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
index 822910b..7d289f1 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
@@ -18,8 +18,6 @@
  */

 package org.apache.felix.ipojo.handlers.dependency;

 

-import java.util.ArrayList;

-import java.util.List;

 

 /**

  * Object managing thread local copy of required services.

@@ -31,19 +29,40 @@
     /**

      * Structure contained in the Thread Local.

      */

-    private class Usage {

+    public class Usage {

+        

         /**

          * Stack Size.

          */

-        Integer m_stack = new Integer(0);

-        /**

-         * List of used service references.

-         */

-        List m_refs = new ArrayList();

+        int m_stack = 0;

         /**

          * List of used objects.

          */

-        List m_objects = new ArrayList();

+        Object[] m_objects;

+        

+        /**

+         * Increment the statck level.

+         */

+        public void inc() {

+            m_stack++;

+        }

+        

+        /**

+         * Decrement the stack level.

+         * @return  true if the stack is 0 after the decrement.

+         */

+        public boolean dec() {

+            m_stack--;

+            return m_stack == 0;

+        }

+        

+        /**

+         * Clear the service object array.

+         */

+        public void clear() {

+            m_objects = null;

+        }

+        

     }

     

     /**

@@ -53,45 +72,6 @@
      */

     public Object initialValue() {

         return new Usage();

-    }

-    

-    /**

-     * Get the list of stored references.

-     * @return the list of stored references.

-     */

-    public List getReferences() {

-        Usage use = (Usage) super.get();

-        return use.m_refs;

-    }

-    

-    /**

-     * Get the lost of stored object.

-     * @return the list of stored service objects.

-     */

-    public List getObjects() {

-        Usage use = (Usage) super.get();

-        return use.m_objects;

-    }

-    

-    /**

-     * Get the stack level.

-     * @return the stack level.

-     */

-    public int getStackLevel() {

-        Usage use = (Usage) super.get();

-        return use.m_stack.intValue();

-    }

-    

-    /**

-     * Set the stack level.

-     * @param level : the new stack level.

-     */

-    public void setStackLevel(int level) {

-        Usage use = (Usage) super.get();

-        use.m_stack = new Integer(level);

-    }

-    

-    

-    

+    }   

 

 }

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
index 15db443..cd86798 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
@@ -53,29 +53,29 @@
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method metadata to invoke
+     * @param method : method metadata to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, MethodMetadata mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, MethodMetadata method) {
         m_transition = transition;
-        m_callback = new Callback(mm, hh.getInstanceManager());
+        m_callback = new Callback(method, handler.getInstanceManager());
     }
     
     /**
      * LifecycleCallback constructor.
      * 
-     * @param hh : the callback handler calling the callback
+     * @param handler : the callback handler calling the callback
      * @param transition : transition on which calling the callback
-     * @param mm : method name to invoke
+     * @param method : method name to invoke
      */
-    public LifecycleCallback(LifecycleCallbackHandler hh, int transition, String mm) {
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, String method) {
         m_transition = transition;
-        m_callback = new Callback(mm, new String[0], false, hh.getInstanceManager());
+        m_callback = new Callback(method, new String[0], false, handler.getInstanceManager());
     }
 
     /**
-     * Call the callback method when the transition from inital to final state is
+     * Call the callback method when the transition from inital tostate is
      * detected.
      * 
      * @throws NoSuchMethodException : Method is not found in the class
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
index 7b153ef..85ca69a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
@@ -26,9 +26,8 @@
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.parser.PojoMetadata;
 
 /**
  * Lifecycle callback handler.
@@ -54,11 +53,11 @@
     /**
      * Add the given callback to the callback list.
      * 
-     * @param hk : the element to add
+     * @param callback : the element to add
      */
-    private void addCallback(LifecycleCallback hk) {
+    private void addCallback(LifecycleCallback callback) {
         for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
-            if (m_callbacks[i] == hk) {
+            if (m_callbacks[i] == callback) {
                 return;
             }
         }
@@ -66,10 +65,10 @@
         if (m_callbacks.length > 0) {
             LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
             System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
-            newHk[m_callbacks.length] = hk;
+            newHk[m_callbacks.length] = callback;
             m_callbacks = newHk;
         } else {
-            m_callbacks = new LifecycleCallback[] { hk };
+            m_callbacks = new LifecycleCallback[] { callback };
         }
 
     }
@@ -87,38 +86,38 @@
         String imm = metadata.getAttribute("immediate");
         m_immediate = imm != null && imm.equalsIgnoreCase("true");
         
-        ManipulationMetadata mm = new ManipulationMetadata(metadata);
+        PojoMetadata meta = getFactory().getPojoMetadata();
 
         Element[] hooksMetadata = metadata.getElements("callback");
-        for (int i = 0; i < hooksMetadata.length; i++) {
+        for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
             String method = hooksMetadata[i].getAttribute("method");
             if (method == null) {
                 throw new ConfigurationException("Lifecycle callback : A callback needs to contains a method attribute");
             }
             
-            MethodMetadata met = mm.getMethod(method, new String[0]);
+            MethodMetadata met = meta.getMethod(method, new String[0]);
             
             int transition = -1;
             String trans = hooksMetadata[i].getAttribute("transition");
-            if (trans != null) {
+            if (trans == null) {
+                throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
+            } else {
                 if (trans.equalsIgnoreCase("validate")) {
                     transition = LifecycleCallback.VALIDATE;
                 } else if (trans.equalsIgnoreCase("invalidate")) {
                     transition = LifecycleCallback.INVALIDATE; 
                 } else {
-                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + transition);
+                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
                 }
-            } else {
-                throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition");
             }
             
-            LifecycleCallback hk = null;
-            if (met != null) { 
-                hk = new LifecycleCallback(this, transition, met);
+            LifecycleCallback callback = null;
+            if (met == null) {
+                callback = new LifecycleCallback(this, transition, method);
             } else {
-                hk = new LifecycleCallback(this, transition, method);
+                callback = new LifecycleCallback(this, transition, met);
             }
-            addCallback(hk);
+            addCallback(callback);
         }
     }
 
@@ -127,7 +126,8 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-    } // Do nothing during the start
+     // Do nothing during the start
+    } 
 
     /**
      * Stop the handler.
@@ -162,13 +162,13 @@
                 try {
                     m_callbacks[i].call();
                 } catch (NoSuchMethodException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (IllegalAccessException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e);
-                    getInstanceManager().stop();
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible");
+                    throw new IllegalStateException(e.getMessage());
                 } catch (InvocationTargetException e) {
-                    log(Logger.ERROR, "[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage());
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
                     getInstanceManager().setState(ComponentInstance.INVALID);
                 }
             }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
index 41b7250..6d00b3b 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
@@ -24,11 +24,10 @@
 import org.apache.felix.ipojo.ConfigurationException;

 import org.apache.felix.ipojo.InstanceManager;

 import org.apache.felix.ipojo.PrimitiveHandler;

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

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

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

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

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

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

+import org.apache.felix.ipojo.parser.PojoMetadata;

 

 /**

  * Lifecycle Controller handler.

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

      */

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

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

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

-        getInstanceManager().register(this, new FieldMetadata[] {new FieldMetadata(field, "boolean")}, null);

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

+        String field = controller[0].getAttribute("field");   

+        getInstanceManager().register(new FieldMetadata(field, "boolean"), this);

     }

 

     /**

@@ -70,38 +69,42 @@
      * Nothing to do. 

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

      */

-    public void stop() { }

+    public void stop() { 

+        // Nothing to do.

+    }

     

     /**

      * GetterCallback.

+     * @param pojo : the pojo object on which the field is accessed

      * Return the stored value.

      * @param field : field name.

-     * @param o : value given by the previous handler.

+     * @param value : value given by the previous handler.

      * @return : the handler state.

      */

-    public Object getterCallback(String field, Object o) {

+    public Object onGet(Object pojo, String field, Object value) {

         return new Boolean(m_state);

     }

     

     /**

      * SetterCallback.

+     * @param pojo : the pojo object on which the field is accessed

      * Store the new field value & invalidate / validate the handler is required.

      * @param field : field name.

-     * @param o : new value.

+     * @param value : new value.

      */

-    public void setterCallback(String field, Object o) {

-        if (o instanceof Boolean) {

-            boolean nv = ((Boolean) o).booleanValue();

-            if (nv != m_state) {

-                m_state = nv;

+    public void onSet(Object pojo, String field, Object value) {

+        if (value instanceof Boolean) {

+            boolean newValue = ((Boolean) value).booleanValue();

+            if (newValue != m_state) {

+                m_state = newValue;

                 if (m_state) {

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

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

                 } else {

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

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

                 }

             }

         } else {

-            log(Logger.ERROR, "Boolean expected for the lifecycle controller");

+            error("Boolean expected for the lifecycle controller");

             getInstanceManager().stop();

         }

     }

@@ -109,28 +112,28 @@
     /**

      * Initialize the component factory.

      * The controller field is checked to avoid configure check.

-     * @param cd : component description

+     * @param desc : component description

      * @param metadata : component type metadata

      * @throws ConfigurationException : occurs if the controller field is not in the POJO class or is not a boolean.

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

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

      */

-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {

+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {

         String field = null;

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

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

         // Use only the first controller

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

+        field = controller[0].getAttribute("field");

         if (field == null) {

             throw new ConfigurationException("Lifecycle controller : the controller element needs to have a field attribute");

         }

         

-        ManipulationMetadata mm = new ManipulationMetadata(metadata);

-        FieldMetadata fm = mm.getField(field);

-        if (fm == null) {

+        PojoMetadata method = getFactory().getPojoMetadata();

+        FieldMetadata fieldMetadata = method.getField(field);

+        if (fieldMetadata == null) {

             throw new ConfigurationException("Lifecycle controller : The field " + field + " does not exist in the class");

         }

         

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

-            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fm.getFieldType() + " found)");

+        if (!fieldMetadata.getFieldType().equalsIgnoreCase("boolean")) {

+            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fieldMetadata.getFieldType() + " found)");

         }

     }

 

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
deleted file mode 100644
index f6b3b6f..0000000
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.handlers.providedservice;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.felix.ipojo.ComponentInstance;
-import org.apache.felix.ipojo.parser.ParseUtils;
-import org.apache.felix.ipojo.util.Logger;
-
-/**
- * Represent a property i.e. a set : [name, type, value]. A property can be
- * attached to a field. The value of the property is thefield value. When the
- * value change, the published value change too.
- * 
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class Property {
-
-    /**
-     * A property is link with a service. This field represent this provided
-     * service. m_providedService : ProvidedService
-     */
-    private ProvidedService m_providedService;
-
-    /**
-     * Value of the property (before we know the type).
-     */
-    private Object m_value;
-
-    /**
-     * Field of the property.
-     */
-    private String m_field;
-
-    /**
-     * Name of the property.
-     */
-    private String m_name;
-
-    /**
-     * Type of the property.
-     */
-    private String m_type;
-
-    /**
-     * String value of the property (initial value).
-     */
-    private String m_initialValue;
-
-    /**
-     * Property constructor.
-     * 
-     * @param ps : the provided service
-     * @param name : name of the property
-     * @param field : name of the field (if a field is attached to the property)
-     * @param type : type of the property
-     * @param value : initial value of the property
-     */
-    public Property(ProvidedService ps, String name, String field, String type, String value) {
-        m_providedService = ps;
-        m_name = name;
-        m_field = field;
-        m_type = type;
-        m_initialValue = value;
-
-        // Dynamic property case :
-        if (m_field != null && m_name == null) {
-            m_name = m_field;
-        }
-
-        if (m_initialValue != null) {
-            setValue(m_initialValue);
-        }
-    }
-
-    /**
-     * Property constructor. This constructor is used only for non-field
-     * property (property not attached to a field).
-     * 
-     * @param ps : the provided service
-     * @param name : the name of the property
-     * @param value : the value of the property
-     */
-    public Property(ProvidedService ps, String name, Object value) {
-        m_providedService = ps;
-        m_name = name;
-        m_type = value.getClass().getName();
-        m_value = value;
-    }
-
-    /**
-     * Get the property value.
-     * @return the Object value of the property
-     */
-    protected Object get() {
-        return m_value;
-    }
-
-    /**
-     * This method is automaticaly called when the value of the property is
-     * changed. Set the value of a property.
-     * 
-     * @param s : the new value of the property (in String)
-     */
-    protected void set(String s) {
-        setValue(s);
-    }
-
-    /**
-     * This method is called when the value of the property is changed. Set the
-     * value of a property.
-     * 
-     * @param o : the new value of the property (object)
-     */
-    protected void set(Object o) {
-        // Is the object is directly assignable to the property, affect it.
-        if (!(o instanceof String) || m_type.equals("java.lang.String")) {
-            m_value = o;
-        } else {
-            // If the object is a String, we must recreate the object from the String form
-            if (o instanceof String) {
-                setValue((String) o);
-            } else {
-                // Error, the given property cannot be injected.
-                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type + " expected");
-            }
-        }
-    }
-
-    /**
-     * Set the provided service of this property.
-     * 
-     * @param ps : the provided service to attached.
-     */
-    void setProvidedService(ProvidedService ps) {
-        m_providedService = ps;
-    }
-
-    /**
-     * Set the value of the property.
-     * 
-     * @param value : value of the property (String)
-     */
-    private void setValue(String value) {
-
-        // Array :
-        if (m_type.endsWith("[]")) {
-            String internalType = m_type.substring(0, m_type.length() - 2);
-            setArrayValue(internalType, ParseUtils.parseArrays(value));
-            return;
-        }
-
-        // Simple :
-        if ("string".equals(m_type) || "String".equals(m_type)) {
-            m_value = new String(value);
-            return;
-        }
-        if ("boolean".equals(m_type)) {
-            m_value = new Boolean(value);
-            return;
-        }
-        if ("byte".equals(m_type)) {
-            m_value = new Byte(value);
-            return;
-        }
-        if ("short".equals(m_type)) {
-            m_value = new Short(value);
-            return;
-        }
-        if ("int".equals(m_type)) {
-            m_value = new Integer(value);
-            return;
-        }
-        if ("long".equals(m_type)) {
-            m_value = new Long(value);
-            return;
-        }
-        if ("float".equals(m_type)) {
-            m_value = new Float(value);
-            return;
-        }
-        if ("double".equals(m_type)) {
-            m_value = new Double(value);
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(m_type);
-            // Class string =
-            // m_providedService.getComponentManager().getContext().getBundle().loadClass("java.lang.String");
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            m_value = cst.newInstance(new Object[] { value });
-        } catch (ClassNotFoundException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (SecurityException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security Exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (NoSuchMethodException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exeption in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalArgumentException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (InstantiationException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in setValue on " + m_type);
-            m_providedService.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + m_type + " : " + e.getTargetException().getMessage());
-            m_providedService.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Set a array value to the current property.
-     * 
-     * @param internalType : internal array type
-     * @param values : the new value
-     */
-    private void setArrayValue(String internalType, String[] values) {
-        if ("string".equals(internalType) || "String".equals(internalType)) {
-            m_value = values;
-            return;
-        }
-        if ("boolean".equals(internalType)) {
-            boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) {
-                bool[i] = new Boolean(values[i]).booleanValue();
-            }
-            m_value = bool;
-            return;
-        }
-        if ("byte".equals(internalType)) {
-            byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) {
-                byt[i] = new Byte(values[i]).byteValue();
-            }
-            m_value = byt;
-            return;
-        }
-        if ("short".equals(internalType)) {
-            short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) {
-                shor[i] = new Short(values[i]).shortValue();
-            }
-            m_value = shor;
-            return;
-        }
-        if ("int".equals(internalType)) {
-            int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) {
-                in[i] = new Integer(values[i]).intValue();
-            }
-            m_value = in;
-            return;
-        }
-        if ("long".equals(internalType)) {
-            long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) {
-                ll[i] = new Long(values[i]).longValue();
-            }
-            m_value = ll;
-            return;
-        }
-        if ("float".equals(internalType)) {
-            float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) {
-                fl[i] = new Float(values[i]).floatValue();
-            }
-            m_value = fl;
-            return;
-        }
-        if ("double".equals(internalType)) {
-            double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) {
-                dl[i] = new Double(values[i]).doubleValue();
-            }
-            m_value = dl;
-            return;
-        }
-
-        // Else it is a neither a primitive type neither a String -> create the
-        // object by calling a constructor with a string in argument.
-        try {
-            Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(internalType);
-            Constructor cst = c.getConstructor(new Class[] { String.class });
-            Object[] ob = (Object[]) Array.newInstance(c, values.length);
-            for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] { values[i] });
-            }
-            m_value = ob;
-            return;
-        } catch (ClassNotFoundException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Class not found exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (SecurityException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Security Exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (NoSuchMethodException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Constructor not found exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalArgumentException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Argument problem to call the constructor of the type " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (InstantiationException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Instantiation problem  " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (IllegalAccessException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Illegal Access Exception in setArrayValue on " + internalType);
-            m_providedService.getInstanceManager().stop();
-        } catch (InvocationTargetException e) {
-            m_providedService.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Invocation problem " + internalType + " : " + e.getTargetException().getMessage());
-            m_providedService.getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Get the stored value.
-     * @return the value of the property.
-     */
-    public Object getValue() {
-        return m_value;
-    }
-
-    /**
-     * Get the property name.
-     * @return the name of the property
-     */
-    public String getName() {
-        return m_name;
-    }
-
-    /**
-     * Get the property field.
-     * @return the field name of the property (null if the property has no
-     * field).
-     */
-    protected String getField() {
-        return m_field;
-    }
-
-    /**
-     * Set the type of the property.
-     * 
-     * @param type : the type to attached to the property
-     */
-    public void setType(String type) {
-        m_type = type;
-    }
-
-    /**
-     * Get the property type.
-     * @return the type of the property.
-     */
-    public String getType() {
-        return m_type;
-    }
-
-    /**
-     * Get the property initial value.
-     * @return the initial value of the property.
-     */
-    public String getInitialValue() {
-        return m_initialValue;
-    }
-
-}
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index ee1248a..4f1d52c 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -22,8 +22,9 @@
 import java.util.Enumeration;
 import java.util.Properties;
 
+import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.InstanceManager;
-import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
@@ -55,6 +56,11 @@
      * Factory policy : SERVICE_FACTORY.
      */
     public static final int SERVICE_FACTORY = 1;
+    
+    /**
+     * Factory policy : STATIC_FACTORY.
+     */
+    public static final int STATIC_FACTORY = 2;
 
     /**
      * At this time, it is only the java interface full name.
@@ -80,7 +86,7 @@
     /**
      * Properties Array.
      */
-    private Property[] m_properties = new Property[0];
+    private Property[] m_properties;
 
     /**
      * Construct a provided service object.
@@ -96,8 +102,12 @@
         m_factoryPolicy = factoryPolicy;
         
         // Add instance name & factory name
-        addProperty(new Property(this, "instance.name", handler.getInstanceManager().getInstanceName()));       
-        addProperty(new Property(this, "factory.name", handler.getInstanceManager().getFactory().getName()));
+        try {
+            addProperty(new Property("instance.name", null, null, handler.getInstanceManager().getInstanceName(), String.class.getName(), handler.getInstanceManager(), handler));       
+            addProperty(new Property("factory.name", null, null, handler.getInstanceManager().getFactory().getFactoryName(), String.class.getName(), handler.getInstanceManager(), handler));
+        } catch (ConfigurationException e) {
+            m_handler.error("An exception occurs when adding instance.name and factory.name property : " + e.getMessage());
+        }
     }
 
     /**
@@ -113,22 +123,22 @@
     /**
      * Add the given property to the property list.
      * 
-     * @param p : the element to add
+     * @param prop : the element to add
      */
-    private synchronized void addProperty(Property p) {
+    private synchronized void addProperty(Property prop) {
         for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
-            if (m_properties[i] == p) {
+            if (m_properties[i] == prop) {
                 return;
             }
         }
 
-        if (m_properties.length > 0) {
+        if (m_properties == null) {
+            m_properties = new Property[] { prop };
+        } else {
             Property[] newProp = new Property[m_properties.length + 1];
             System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
-            newProp[m_properties.length] = p;
+            newProp[m_properties.length] = prop;
             m_properties = newProp;
-        } else {
-            m_properties = new Property[] { p };
         }
     }
 
@@ -148,7 +158,7 @@
 
         if (idx >= 0) {
             if ((m_properties.length - 1) == 0) {
-                m_properties = new Property[0];
+                m_properties = null;
             } else {
                 Property[] newPropertiesList = new Property[m_properties.length - 1];
                 System.arraycopy(m_properties, 0, newPropertiesList, 0, idx);
@@ -166,10 +176,10 @@
      * service is not published).
      */
     public ServiceReference getServiceReference() {
-        if (m_serviceRegistration != null) {
-            return m_serviceRegistration.getReference();
-        } else {
+        if (m_serviceRegistration == null) {
             return null;
+        } else {
+            return m_serviceRegistration.getReference();
         }
     }
 
@@ -189,9 +199,14 @@
             case SERVICE_FACTORY:
                 svc = m_handler.getInstanceManager().createPojoObject();
                 break;
+            case STATIC_FACTORY:
+                // In this case, we need to try to create a new pojo object, the factory method will handle the creation.
+                svc = m_handler.getInstanceManager().createPojoObject();
+                break;
             default:
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
+                m_handler.error("[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
                 getInstanceManager().stop();
+                break;
         }
         return svc;
     }
@@ -258,8 +273,8 @@
         // Contruct the service properties list
         Properties serviceProperties = new Properties();
         for (int i = 0; i < m_properties.length; i++) {
-            if (m_properties[i].get() != null) {
-                serviceProperties.put(m_properties[i].getName(), m_properties[i].get());
+            if (m_properties[i].getValue() != null) {
+                serviceProperties.put(m_properties[i].getName(), m_properties[i].getValue());
             }
         }
         return serviceProperties;
@@ -278,18 +293,9 @@
      * the service registry.
      */
     public synchronized void update() {
-        // Contruct the service properties list
-        Properties serviceProperties = getServiceProperties();
-
-        if (serviceProperties == null) {
-            m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Cannot get the properties of the provided service");
-            getInstanceManager().stop();
-            return;
-        }
-
         // Update the service registration
         if (m_serviceRegistration != null) {
-            m_serviceRegistration.setProperties(serviceProperties);
+            m_serviceRegistration.setProperties(getServiceProperties());
         }
     }
 
@@ -302,8 +308,13 @@
         while (keys.hasMoreElements()) {
             String key = (String) keys.nextElement();
             Object value = props.get(key);
-            Property prop = new Property(this, key, value);
-            addProperty(prop);
+            Property prop;
+            try {
+                prop = new Property(key, null, null, value.toString(), value.getClass().getName(), getInstanceManager(), m_handler);
+                addProperty(prop);
+            } catch (ConfigurationException e) {
+                m_handler.error("The propagated property " + key + " cannot be pcreated correctly : " + e.getMessage());
+            }
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
index 59f2cda..d8fe68a 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
@@ -69,13 +69,13 @@
      * 
      * @param serviceSpecification : the provided contract
      * @param state : state (UNREGITRED | REGISTRED)
-     * @param sr : Service Registration (to obtain the reference), or null if
+     * @param ref : Service Registration (to obtain the reference), or null if
      * state is UNREGISTRED
      */
-    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference sr) {
+    public ProvidedServiceDescription(String[] serviceSpecification, int state, ServiceReference ref) {
         m_serviceSpecification = serviceSpecification;
         m_state = state;
-        m_serviceReference = sr;
+        m_serviceReference = ref;
         // m_parent = parent;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index a791797..1fc3e1d 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -19,7 +19,6 @@
 package org.apache.felix.ipojo.handlers.providedservice;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -28,10 +27,10 @@
 import java.util.Set;
 
 import org.apache.felix.ipojo.ConfigurationException;
-import org.apache.felix.ipojo.IPojoConfiguration;
+import org.apache.felix.ipojo.HandlerFactory;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
-import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.dependency.Dependency;
@@ -40,9 +39,10 @@
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
 import org.apache.felix.ipojo.parser.ManifestMetadataParser;
-import org.apache.felix.ipojo.parser.ManipulationMetadata;
 import org.apache.felix.ipojo.parser.ParseException;
 import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Property;
 import org.osgi.framework.Bundle;
 
 /**
@@ -60,21 +60,21 @@
     /**
      * Add a provided service to the list .
      * 
-     * @param ps : the provided service to add
+     * @param svc : the provided service to add
      */
-    private void addProvidedService(ProvidedService ps) {
+    private void addProvidedService(ProvidedService svc) {
         // Verify that the provided service is not already in the array.
         for (int i = 0; (m_providedServices != null) && (i < m_providedServices.length); i++) {
-            if (m_providedServices[i] == ps) { return; }
+            if (m_providedServices[i] == svc) { return; }
         }
 
         if (m_providedServices.length > 0) {
             ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
             System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
-            newPS[m_providedServices.length] = ps;
+            newPS[m_providedServices.length] = svc;
             m_providedServices = newPS;
         } else {
-            m_providedServices = new ProvidedService[] { ps };
+            m_providedServices = new ProvidedService[] { svc };
         }
     }
 
@@ -97,7 +97,6 @@
         m_providedServices = new ProvidedService[0];
         // Create the dependency according to the component metadata
         Element[] providedServices = componentMetadata.getElements("Provides");
-        List fields = new ArrayList();
         for (int i = 0; i < providedServices.length; i++) {
             String[] serviceSpecifications = ParseUtils.parseArrays(providedServices[i].getAttribute("interface")); // Set by the initialize component factory.
             
@@ -107,62 +106,54 @@
             if (fact != null && "service".equalsIgnoreCase(fact)) {
                 factory = ProvidedService.SERVICE_FACTORY;
             }
-
-            // Then create the provided service
-            ProvidedService ps = new ProvidedService(this, serviceSpecifications, factory);
-
-            Element[] props = providedServices[i].getElements("Property");
-            Property[] properties = new Property[props.length];
-            for (int j = 0; j < props.length; j++) {
-                String name = props[j].getAttribute("name");
-                String value = props[j].getAttribute("value");
-                String type = props[j].getAttribute("type");
-                String field = props[j].getAttribute("field");
-
-                if (name != null && configuration.get(name) != null && configuration.get(name) instanceof String) {
-                    value = (String) configuration.get(name);
-                } else {
-                    if (field != null && configuration.get(field) != null && configuration.get(field) instanceof String) {
-                        value = (String) configuration.get(field);
-                    }
-                }
-
-                Property prop = new Property(ps, name, field, type, value);
-                properties[j] = prop;
-                
-                // Check if the instance configuration has a value for this property
-                Object o = configuration.get(prop.getName()); 
-                if (o != null && ! (o instanceof String)) {
-                    prop.set(o);
-                } else {
-                    if (field != null) {
-                        o = configuration.get(field);
-                        if (o != null && !(o instanceof String)) {
-                            prop.set(configuration.get(field));
-                        }
-                    }
-                }
-                
-                if (field != null) {
-                    fields.add(new FieldMetadata(field, type));
-                }
+            if (fact != null && "method".equalsIgnoreCase(fact)) {
+                factory = ProvidedService.STATIC_FACTORY;
             }
 
-            // Attached to properties to the provided service
-            ps.setProperties(properties);
+            // Then create the provided service
+            ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory);
 
-            if (checkProvidedService(ps)) {
-                addProvidedService(ps);
+            Element[] props = providedServices[i].getElements("Property");
+            if (props != null) {
+                //Property[] properties = new Property[props.length];
+                Property[] properties = new Property[props.length];
+                for (int j = 0; j < props.length; j++) {
+                    String name = props[j].getAttribute("name");
+                    String value = props[j].getAttribute("value");
+                    String type = props[j].getAttribute("type");
+                    String field = props[j].getAttribute("field");
+
+                    Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
+                    properties[j] = prop;
+
+                    // Check if the instance configuration has a value for this property                    
+                    Object object = configuration.get(prop.getName());
+                    if (object != null) {
+                        prop.setValue(object);
+                    }
+                    
+                    if (field != null) {
+                        getInstanceManager().register(new FieldMetadata(field, type), this);
+                        // Cannot register the property as the interception is necessary to deal with registration update.
+                    }
+                }
+
+                // Attach to properties to the provided service
+                svc.setProperties(properties);
+            }
+
+            if (checkProvidedService(svc)) {
+                addProvidedService(svc);
             } else {
-                String itfs = "";
+                StringBuffer itfs = new StringBuffer();
                 for (int j = 0; j < serviceSpecifications.length; j++) {
-                    itfs = itfs + " " + serviceSpecifications[j];
+                    itfs.append(' ');
+                    itfs.append(serviceSpecifications[j]);
                 }
                 throw new ConfigurationException("[" + getInstanceManager().getInstanceName() + "] The provided service" + itfs + " is not valid");                
             }
 
         }
-        getInstanceManager().register(this, (FieldMetadata[]) fields.toArray(new FieldMetadata[fields.size()]), null);
     }
     
     /**
@@ -185,8 +176,8 @@
 
         // Look for parent class.
         if (parent != null) {
-            Class cl = bundle.loadClass(parent);
-            collectInterfacesFromClass(cl, result, bundle);
+            Class clazz = bundle.loadClass(parent);
+            collectInterfacesFromClass(clazz, result, bundle);
         }
 
         return result;
@@ -195,78 +186,78 @@
     /**
      * Look for inherited interfaces.
      * @param clazz : interface name to explore (class object)
-     * @param l : set (accumulator)
-     * @param b : bundle
+     * @param acc : set (accumulator)
+     * @param bundle : bundle
      * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
      */
-    private void collectInterfaces(Class clazz, Set l, Bundle b) throws ClassNotFoundException {
+    private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
         Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
     }
     
     /**
      * Collect interfaces for the given class.
      * This method explores super class to.
-     * @param cl : class object.
-     * @param l : set of implemented interface (accumulator)
-     * @param b : bundle.
+     * @param clazz : class object.
+     * @param acc : set of implemented interface (accumulator)
+     * @param bundle : bundle.
      * @throws ClassNotFoundException : occurs if an interface cannot be load.
      */
-    private void collectInterfacesFromClass(Class cl, Set l, Bundle b) throws ClassNotFoundException {
-        Class[] clazzes = cl.getInterfaces();
+    private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class[] clazzes = clazz.getInterfaces();
         for (int i = 0; i < clazzes.length; i++) {
-            l.add(clazzes[i].getName());
-            collectInterfaces(clazzes[i], l, b);
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
         }
         // Iterate on parent classes
-        Class sup = cl.getSuperclass();
+        Class sup = clazz.getSuperclass();
         if (sup != null) {
-            collectInterfacesFromClass(sup, l, b);
+            collectInterfacesFromClass(sup, acc, bundle);
         }
     }
 
     /**
      * Check the provided service given in argument in the sense that the metadata are consistent.
-     * @param ps : the provided service to check.
+     * @param svc : the provided service to check.
      * @return true if the provided service is correct
      * @throws ConfigurationException : the checked provided service is not correct.
      */
-    private boolean checkProvidedService(ProvidedService ps) throws ConfigurationException {        
-        for (int i = 0; i < ps.getServiceSpecification().length; i++) {
-            String specName = ps.getServiceSpecification()[i];
+    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {        
+        for (int i = 0; i < svc.getServiceSpecification().length; i++) {
+            String specName = svc.getServiceSpecification()[i];
             
             // Check service level dependencies
             try {
                 Class spec = getInstanceManager().getFactory().loadClass(specName);
                 Field specField = spec.getField("specification");
-                Object o = specField.get(null);
-                if (o instanceof String) {
-                    Element specification = ManifestMetadataParser.parse((String) o);
+                Object specif = specField.get(null);
+                if (specif instanceof String) {
+                    Element specification = ManifestMetadataParser.parse((String) specif);
                     Element[] deps = specification.getElements("requires");
-                    for (int j = 0; j < deps.length; j++) {
-                        Dependency d = getAttachedDependency(deps[j]);
-                        if (d != null) {
+                    for (int j = 0; deps != null && j < deps.length; j++) {
+                        Dependency dep = getAttachedDependency(deps[j]);
+                        if (dep != null) {
                             // Fix service-level dependency flag
-                            d.setServiceLevelDependency();
+                            dep.setServiceLevelDependency();
                         }
-                        isDependencyCorrect(d, deps[j]);
+                        isDependencyCorrect(dep, deps[j]);
                     }
                 } else {
-                    throw new ConfigurationException("Provides  : The specification field of the service specification " + ps.getServiceSpecification()[i] + " need to be a String");
+                    throw new ConfigurationException("Provides  : The specification field of the service specification " + svc.getServiceSpecification()[i] + " need to be a String");
                 }
             } catch (NoSuchFieldException e) {
                 return true; // No specification field
             } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Provides  : The service specification " + ps.getServiceSpecification()[i] + " cannot be load");
+                throw new ConfigurationException("Provides  : The service specification " + svc.getServiceSpecification()[i] + " cannot be load");
             } catch (IllegalArgumentException e) {
-                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
+                throw new ConfigurationException("Provides  : The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " is not accessible : " + e.getMessage());
             } catch (ParseException e) {
-                throw new ConfigurationException("Provides  :  The field 'specification' of the service specification " + ps.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
+                throw new ConfigurationException("Provides  :  The field 'specification' of the service specification " + svc.getServiceSpecification()[i] + " does not contain a valid String : " + e.getMessage());
             }
         }
 
@@ -279,20 +270,20 @@
      * @return the Dependency object, null if not found or if the DependencyHandler is not plugged to the instance
      */
     private Dependency getAttachedDependency(Element element) {
-        DependencyHandler dh = (DependencyHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires");
-        if (dh == null) { return null; }
+        DependencyHandler handler = (DependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":requires");
+        if (handler == null) { return null; }
 
-        String id = element.getAttribute("id");
-        if (id != null) {
+        String identity = element.getAttribute("id");
+        if (identity != null) {
             // Look for dependency Id
-            for (int i = 0; i < dh.getDependencies().length; i++) {
-                if (dh.getDependencies()[i].getId().equals(id)) { return dh.getDependencies()[i]; }
+            for (int i = 0; i < handler.getDependencies().length; i++) {
+                if (handler.getDependencies()[i].getId().equals(identity)) { return handler.getDependencies()[i]; }
             }
         }
         // If not found or no id, look for a dependency with the same specification
         String requirement = element.getAttribute("specification");
-        for (int i = 0; i < dh.getDependencies().length; i++) {
-            if (dh.getDependencies()[i].getSpecification().equals(requirement)) { return dh.getDependencies()[i]; }
+        for (int i = 0; i < handler.getDependencies().length; i++) {
+            if (handler.getDependencies()[i].getSpecification().equals(requirement)) { return handler.getDependencies()[i]; }
         }
 
         return null;
@@ -334,6 +325,7 @@
      * @see org.apache.felix.ipojo.Handler#stop()
      */
     public void stop() {
+        //Nothing to do.
     }
 
     /**
@@ -341,31 +333,34 @@
      * 
      * @see org.apache.felix.ipojo.Handler#start()
      */
-    public void start() { }
+    public void start() {
+        // Nothing to do.
+    }
 
     /**
      * Setter Callback Method.
      * Check if the modified field is a property to update the value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : new value
-     * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onSet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public void setterCallback(String fieldName, Object value) {
+    public void onSet(Object pojo, String fieldName, Object value) {
         // Verify that the field name correspond to a dependency
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
+            ProvidedService svc = m_providedServices[i];
             boolean update = false;
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
-                if (fieldName.equals(prop.getField())) {
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
+                if (fieldName.equals(prop.getField()) && ! prop.getValue().equals(value)) {
                     // it is the associated property
-                    prop.set(value);
+                    prop.setValue(value);
                     update = true;
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
         // Else do nothing
@@ -374,20 +369,21 @@
     /**
      * Getter Callback Method.
      * Check if the field is a property to push the stored value.
+     * @param pojo : the pojo object on which the field is accessed
      * @param fieldName : field name
      * @param value : value pushed by the previous handler
      * @return the stored value or the previous value.
-     * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String,
-     * java.lang.Object)
+     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+     * java.lang.String, java.lang.Object)
      */
-    public Object getterCallback(String fieldName, Object value) {
+    public Object onGet(Object pojo, String fieldName, Object value) {
         for (int i = 0; i < m_providedServices.length; i++) {
-            ProvidedService ps = m_providedServices[i];
-            for (int j = 0; j < ps.getProperties().length; j++) {
-                Property prop = ps.getProperties()[j];
+            ProvidedService svc = m_providedServices[i];
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
                 if (fieldName.equals(prop.getField())) {
                     // it is the associated property
-                    return prop.get();
+                    return prop.getValue();
                 }
             }
         }
@@ -452,12 +448,12 @@
         ProvidedServiceHandlerDescription pshd = new ProvidedServiceHandlerDescription(this);
 
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            ProvidedServiceDescription psd = new ProvidedServiceDescription(ps.getServiceSpecification(), ps.getState(), ps.getServiceReference());
+            ProvidedService svc = getProvidedService()[j];
+            ProvidedServiceDescription psd = new ProvidedServiceDescription(svc.getServiceSpecification(), svc.getState(), svc.getServiceReference());
 
             Properties props = new Properties();
-            for (int k = 0; k < ps.getProperties().length; k++) {
-                Property prop = ps.getProperties()[k];
+            for (int k = 0; k < svc.getProperties().length; k++) {
+                Property prop = svc.getProperties()[k];
                 if (prop.getValue() != null) {
                     props.put(prop.getName(), prop.getValue().toString());
                 }
@@ -475,36 +471,32 @@
      */
     public void reconfigure(Dictionary dict) {
         for (int j = 0; j < getProvidedService().length; j++) {
-            ProvidedService ps = getProvidedService()[j];
-            Property[] props = ps.getProperties();
+            ProvidedService svc = getProvidedService()[j];
+            Property[] props = svc.getProperties();
             boolean update = false;
             for (int k = 0; k < props.length; k++) {
                 if (dict.get(props[k].getName()) != null) {
                     update = true;
-                    if (dict.get(props[k].getName()) instanceof String) {
-                        props[k].set((String) dict.get(props[k].getName()));
-                    } else {
-                        props[k].set(dict.get(props[k].getName()));
-                    }
+                    props[k].setValue(dict.get(props[k].getName()));
                 }
             }
             if (update) {
-                ps.update();
+                svc.update();
             }
         }
     }
 
     /**
      * Initialize the component type.
-     * @param cd : component type description to populate.
+     * @param desc : component type description to populate.
      * @param metadata : component type metadata.
      * @throws ConfigurationException : occurs when the POJO does not implement any interfaces.
-     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
      */
-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
         // Change ComponentInfo
         Element[] provides = metadata.getElements("provides");
-        ManipulationMetadata manipulation = new ManipulationMetadata(metadata);
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
 
         for (int i = 0; i < provides.length; i++) {
          // First : create the serviceSpecification list
@@ -512,7 +504,7 @@
             String parent = manipulation.getSuperClass();
             Set all = null;
             try {
-                all = computeInterfaces(serviceSpecification, parent, cd.getBundleContext().getBundle());
+                all = computeInterfaces(serviceSpecification, parent, desc.getBundleContext().getBundle());
             } catch (ClassNotFoundException e) {
                 throw new ConfigurationException("A interface cannot be loaded : " + e.getMessage());
             }
@@ -522,35 +514,37 @@
                 List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
                 for (int j = 0; j < itfs.size(); j++) {
                     if (! all.contains(itfs.get(j))) {
-                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + cd.getClassName());
+                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + desc.getClassName());
                     }
                 }
                 all = new HashSet(itfs);
             }
             
-            if (all.size() == 0) {
+            if (all.isEmpty()) {
                 throw new ConfigurationException("Provides  : Cannot instantiate a provided service : no specifications found (no interfaces implemented by the pojo)");
             }
 
-            String specs = null;
+            StringBuffer specs = null;
             Set set = new HashSet(all);
-            Iterator it = set.iterator(); 
-            while (it.hasNext()) {
-                String sp = (String) it.next();
-                cd.addProvidedServiceSpecification(sp);
+            Iterator iterator = set.iterator(); 
+            while (iterator.hasNext()) {
+                String spec = (String) iterator.next();
+                desc.addProvidedServiceSpecification(spec);
                 if (specs == null) {
-                    specs = "{" + sp;
+                    specs = new StringBuffer("{");
+                    specs.append(spec);
                 } else {
-                    specs += "," + sp;
+                    specs.append(',');
+                    specs.append(spec);
                 }
             }
             
-            specs += "}";
+            specs.append('}');
             
-            provides[i].addAttribute(new Attribute("interface", specs)); // Add interface attribute to avoid checking in the configure method
+            provides[i].addAttribute(new Attribute("interface", specs.toString())); // Add interface attribute to avoid checking in the configure method
 
             Element[] props = provides[i].getElements("property");
-            for (int j = 0; j < props.length; j++) {
+            for (int j = 0; props != null && j < props.length; j++) {
                 String name = props[j].getAttribute("name");
                 String value = props[j].getAttribute("value");
                 String type = props[j].getAttribute("type");
@@ -566,15 +560,22 @@
                     if (field == null) {
                         throw new ConfigurationException("The property " + name + " has neither type neither field.");
                     }
-                    FieldMetadata fm = manipulation.getField(field);
-                    if (fm == null) {
+                    FieldMetadata fieldMeta = manipulation.getField(field);
+                    if (fieldMeta == null) {
                         throw new ConfigurationException("A declared property was not found in the class : " + field);
                     }
-                    type = fm.getFieldType();
+                    type = fieldMeta.getFieldType();
                     props[j].addAttribute(new Attribute("type", type));
                 }
+                
+                // Is the property set to immutable
+                boolean immutable = false;
+                String imm = props[j].getAttribute("immutable");
+                if (imm != null && imm.equalsIgnoreCase("true")) {
+                    immutable = true;
+                }
 
-                cd.addProperty(new PropertyDescription(name, type, value));
+                desc.addProperty(new PropertyDescription(name, type, value, immutable));
             }
         }
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
index d2bb779..59601f9 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
@@ -40,10 +40,10 @@
 
     /**
      * Constructor.
-     * @param h : handler.
+     * @param handler : handler.
      */
-    public ProvidedServiceHandlerDescription(Handler h) {
-        super(h);
+    public ProvidedServiceHandlerDescription(Handler handler) {
+        super(handler);
     }
 
     /**
@@ -83,17 +83,18 @@
     public Element getHandlerInfo() {
         Element services = super.getHandlerInfo();
         for (int i = 0; i < m_providedServices.length; i++) {
-            Element service = new Element("provides", "");
-            String spec = "[";
+            Element service = new Element("provides", null);
+            StringBuffer spec = new StringBuffer("[");
             for (int j = 0; j < m_providedServices[i].getServiceSpecification().length; j++) {
                 if (j == 0) {
-                    spec += m_providedServices[i].getServiceSpecification()[j];
+                    spec.append(m_providedServices[i].getServiceSpecification()[j]);
                 } else {
-                    spec += ", " + m_providedServices[i].getServiceSpecification()[j];
+                    spec.append(',');
+                    spec.append(m_providedServices[i].getServiceSpecification()[j]);
                 }
             }
-            spec += "]";
-            service.addAttribute(new Attribute("specifications", spec));
+            spec.append(']');
+            service.addAttribute(new Attribute("specifications", spec.toString()));
 
             if (m_providedServices[i].getState() == ProvidedService.REGISTERED) {
                 service.addAttribute(new Attribute("state", "registered"));
@@ -102,12 +103,12 @@
                 service.addAttribute(new Attribute("state", "unregistered"));
             }
             
-            Iterator it = m_providedServices[i].getProperties().keySet().iterator();
-            while (it.hasNext()) {
-                Element prop = new Element("property", "");
-                String k = (String) it.next();
-                prop.addAttribute(new Attribute("name", k));
-                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(k).toString()));
+            Iterator iterator = m_providedServices[i].getProperties().keySet().iterator();
+            while (iterator.hasNext()) {
+                Element prop = new Element("property", null);
+                String name = (String) iterator.next();
+                prop.addAttribute(new Attribute("name", name));
+                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(name).toString()));
                 service.addElement(prop);
             }
             services.addElement(service);
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
index 9c6ea8d..bc272d0 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
@@ -62,45 +62,32 @@
     public String getFieldType() { return m_type; }
     
     /**
-     * Get the 'reflective' type of the field.
+     * Get the 'reflective' type of the given type.
      * The reflective type is the type used by the Java Reflection API.
+     * @param type : the type to analyze to find the Java reflective type.
      * @return : the reflective type corresponding to this field.
      */
-    public String getReflectionType() {
+    public static String getReflectionType(String type) {
         // Primitive Array 
-        if (m_type.endsWith("[]") && m_type.indexOf(".") == -1) {
-            String arr = "";
-            for (int i = 0; i < m_type.length(); i++) {
-                if (m_type.charAt(i) == '[') { arr += '['; }
-            }
-            int index = m_type.indexOf('[');
-            String t = m_type.substring(0, index);
-            return arr + getInternalPrimitiveType(t);
+        if (type.endsWith("[]") && type.indexOf('.') == -1) {
+            int index = type.indexOf('[');
+            return '[' + getInternalPrimitiveType(type.substring(0, index));
         }
         // Non-Primitive Array 
-        if (m_type.endsWith("[]") && m_type.indexOf(".") != -1) {
-            String arr = "";
-            for (int i = 0; i < m_type.length(); i++) {
-                if (m_type.charAt(i) == '[') { arr += '['; }
-            }
-            int index = m_type.indexOf('[');
-            String t = m_type.substring(0, index);
-            return arr + "L" + t + ";";
+        if (type.endsWith("[]") && type.indexOf('.') != -1) {
+            int index = type.indexOf('[');
+            return "[L" + type.substring(0, index) + ";";
         }
-        // Simple type 
-        if (!m_type.endsWith("[]")) {
-            return m_type;
-        }
-        
-        return null;
+        // The type is not an array.
+        return type;
     }
     
     /**
      * Get the internal notation for primitive type.
-     * @param string : Stringform of the type
+     * @param string : String form of the type
      * @return the internal notation or null if not found
      */
-    private String getInternalPrimitiveType(String string) {
+    public static String getInternalPrimitiveType(String string) {
         if (string.equalsIgnoreCase("boolean")) {
             return "Z";
         }
@@ -125,7 +112,39 @@
         if (string.equalsIgnoreCase("double")) {
             return "D";
         }
-        System.err.println("No primitive type found for " + m_type);
+        return null;
+    }
+    
+    /**
+     * Get the iPOJO primitive type from the given primitive class.
+     * @param clazz : a primitive class
+     * @return the primitive type.
+     */
+    public static String getPrimitiveTypeByClass(Class clazz) {
+        if (clazz.equals(Boolean.TYPE)) {
+            return "boolean";
+        }
+        if (clazz.equals(Character.TYPE)) {
+            return "char";
+        }
+        if (clazz.equals(Byte.TYPE)) {
+            return "byte";
+        }
+        if (clazz.equals(Short.TYPE)) {
+            return "short";
+        }
+        if (clazz.equals(Integer.TYPE)) {
+            return "int";
+        }
+        if (clazz.equals(Float.TYPE)) {
+            return "float";
+        }
+        if (clazz.equals(Long.TYPE)) {
+            return "long";
+        }
+        if (clazz.equals(Double.TYPE)) {
+            return "double";
+        }
         return null;
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
index 172338a..ea0709e 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -18,7 +18,9 @@
  */
 package org.apache.felix.ipojo.parser;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.metadata.Attribute;
@@ -32,11 +34,6 @@
 public class ManifestMetadataParser {
 
     /**
-     * Manifest Headers.
-     */
-    private Dictionary m_headers;
-
-    /**
      * Element list.
      */
     private Element[] m_elements = new Element[0];
@@ -47,24 +44,14 @@
      * @throws ParseException when a parsing error occurs
      */
     public Element[] getComponentsMetadata() throws ParseException {
-        Element[] components = m_elements[0].getElements("Component");
-        Element[] composites = m_elements[0].getElements("Composite");
-        Element[] handlers = m_elements[0].getElements("Handler");
-        Element[] all = new Element[components.length + composites.length + handlers.length];
-        int l = 0;
-        for (int i = 0; i < components.length; i++) {
-            all[l] = components[i];
-            l++;
+        Element[] elems = m_elements[0].getElements();
+        List list = new ArrayList();
+        for (int i = 0; i < elems.length; i++) {
+            if (!"instance".equals(elems[i].getName())) {
+                list.add(elems[i]);
+            }
         }
-        for (int i = 0; i < composites.length; i++) {
-            all[l] = composites[i];
-            l++;
-        }
-        for (int i = 0; i < handlers.length; i++) {
-            all[l] = handlers[i];
-            l++;
-        }
-        return all;
+        return (Element[]) list.toArray(new Element[list.size()]);
     }
 
     /**
@@ -73,7 +60,10 @@
      * @throws ParseException : if the metadata cannot be parsed successfully
      */
     public Dictionary[] getInstances() throws ParseException {
-        Element[] configs = m_elements[0].getElements("Instance");
+        Element[] configs = m_elements[0].getElements("instance");
+        if (configs == null) {
+            return null;
+        }
         Dictionary[] dicts = new Dictionary[configs.length];
         for (int i = 0; i < configs.length; i++) {
             dicts[i] = parseInstance(configs[i]);
@@ -95,17 +85,18 @@
         if (name != null) {
             dict.put("name", instance.getAttribute("name"));
         }
-        
+
         if (comp == null) {
             throw new ParseException("An instance does not have the 'component' attribute");
         }
-        
-        dict.put("component", comp);
 
-        for (int i = 0; i < instance.getElements("property").length; i++) {
-            parseProperty(instance.getElements("property")[i], dict);
+        dict.put("component", comp);
+        Element[] props = instance.getElements("property");
+
+        for (int i = 0; props != null && i < props.length; i++) {
+            parseProperty(props[i], dict);
         }
-        
+
         return dict;
     }
 
@@ -122,10 +113,8 @@
         if (name == null) {
             throw new ParseException("A property does not have the 'name' attribute");
         }
-        // Final case : the property element has a 'value' attribute
-        if (value != null) {
-            dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
-        } else {
+        //case : the property element has a 'value' attribute
+        if (value == null) {
             // Recursive case
             // Check if there is 'property' element
             Element[] subProps = prop.getElements("property");
@@ -137,6 +126,8 @@
                 parseProperty(subProps[i], dict2);
                 dict.put(name, dict2);
             }
+        } else {
+            dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
         }
     }
 
@@ -146,13 +137,13 @@
      * @param elem : the element to add
      */
     private void addElement(Element elem) {
-        if (m_elements != null) {
+        if (m_elements == null) {
+            m_elements = new Element[] { elem };
+        } else {
             Element[] newElementsList = new Element[m_elements.length + 1];
             System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
             newElementsList[m_elements.length] = elem;
             m_elements = newElementsList;
-        } else {
-            m_elements = new Element[] { elem };
         }
     }
 
@@ -180,19 +171,18 @@
     }
 
     /**
-     * Parse the given dictionnary and create the instance managers.
+     * Parse the given dictionary and create the instance managers.
      * 
      * @param dict : the given headers of the manifest file
      * @throws ParseException : if any error occurs
      */
     public void parse(Dictionary dict) throws ParseException {
-        m_headers = dict;
-        String componentClassesStr = (String) m_headers.get("iPOJO-Components");
+        String componentClassesStr = (String) dict.get("iPOJO-Components");
         // Add the ipojo element inside the element list
         addElement(new Element("iPOJO", ""));
         parseElements(componentClassesStr.trim());
     }
-    
+
     /**
      * Parse the given header and create the instance managers.
      * 
@@ -222,57 +212,61 @@
     }
 
     /**
-     * Paser the given string.
+     * Parse the given string.
      * 
-     * @param s : the string to parse
+     * @param elems : the string to parse
      */
-    private void parseElements(String s) {
-        char[] string = s.toCharArray();
+    private void parseElements(String elems) {
+        char[] string = elems.toCharArray();
 
         for (int i = 0; i < string.length; i++) {
-            char c = string[i];
+            char current = string[i];
 
-            switch (c) {
+            switch (current) { //NOPMD
                 // Beginning of an attribute.
                 case '$':
-                    String attName = "";
-                    String attValue = "";
-                    String attNs = "";
+                    StringBuffer attName = new StringBuffer();
+                    StringBuffer attValue = new StringBuffer();
+                    StringBuffer attNs = null;
                     i++;
-                    c = string[i];
-                    while (c != '=') {
-                        if (c == ':') {
+                    current = string[i]; // Increment and get the new current char.
+                    while (current != '=') {
+                        if (current == ':') {
                             attNs = attName;
-                            attName = "";
+                            attName = new StringBuffer();
                         } else {
-                            attName = attName + c;
+                            attName.append(current);
                         }
-                        i = i + 1;
-                        c = string[i];
-                    }
-                    i++; // skip =
-                    i++; // skip "
-                    c = string[i];
-                    while (c != '"') {
-                        attValue = attValue + c;
                         i++;
-                        c = string[i];
+                        current = string[i];
+                    }
+                    i = i + 2; // skip ="
+                    current = string[i];
+                    while (current != '"') {
+                        attValue.append(current);
+                        i++;
+                        current = string[i]; // Increment and get the new current char.
                     }
                     i++; // skip "
-                    c = string[i];
+                    current = string[i];
 
-                    Attribute att = new Attribute(attName, attNs, attValue);
+                    Attribute att = null;
+                    if (attNs == null) {
+                        att = new Attribute(attName.toString(), attValue.toString());
+                    } else {
+                        att = new Attribute(attName.toString(), attNs.toString(), attValue.toString());
+                    }
                     m_elements[m_elements.length - 1].addAttribute(att);
                     break;
 
                 // End of an element
                 case '}':
                     Element lastElement = removeLastElement();
-                    if (m_elements.length != 0) {
+                    if (m_elements.length == 0) {
+                        addElement(lastElement);
+                    } else {
                         Element newQueue = m_elements[m_elements.length - 1];
                         newQueue.addElement(lastElement);
-                    } else {
-                        addElement(lastElement);
                     }
                     break;
 
@@ -282,19 +276,19 @@
 
                 // Default case
                 default:
-                    String name = "";
-                    String ns = "";
-                    c = string[i];
-                    while (c != ' ') {
-                        if (c == ':') {
-                            ns = name;
-                            name = "";
+                    StringBuffer name = new StringBuffer();
+                    StringBuffer namespace = null;
+                    current = string[i];
+                    while (current != ' ') {
+                        if (current == ':') {
+                            namespace = name;
+                            name = new StringBuffer();
                             i++;
-                            c = string[i];
+                            current = string[i];
                         } else {
-                            name = name + c;
+                            name.append(current);
                             i++;
-                            c = string[i];
+                            current = string[i]; // Increment and get the new current char.
                         }
                     }
                     // Skip spaces
@@ -302,8 +296,15 @@
                         i = i + 1;
                     }
                     i = i + 1; // skip {
-                    Element elem = new Element(name, ns);
+                    
+                    Element elem = null;
+                    if (namespace == null) {
+                        elem = new Element(name.toString(), null);
+                    } else {
+                        elem = new Element(name.toString(), namespace.toString());
+                    }
                     addElement(elem);
+                    
                     break;
             }
         }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
index 1a8b482..302c2d4 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.ipojo.parser;
 
+import java.lang.reflect.Method;
+
 import org.apache.felix.ipojo.metadata.Element;
 
 /**
@@ -27,22 +29,22 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class MethodMetadata {
-    
+
     /**
      * Name of the method.
      */
     private String m_name;
-    
+
     /**
      * Argument type array. 
      */
     private String[] m_arguments = new String[0];
-    
+
     /**
      * Returned type. 
      */
     private String m_return = "void";
-    
+
     /**
      * Constructor.
      * @param metadata : method manipulation element.
@@ -50,37 +52,77 @@
     MethodMetadata(Element metadata) {
         m_name = metadata.getAttribute("name");
         String arg = metadata.getAttribute("arguments");
-        String rt = metadata.getAttribute("return");
+        String result = metadata.getAttribute("return");
         if (arg != null) {
             m_arguments = ParseUtils.parseArrays(arg);
         }
-        if (rt != null) {
-            m_return = rt;
+        if (result != null) {
+            m_return = result;
         }
     }
-    
-    public String getMethodName() { return m_name; }
-    
-    public String[] getMethodArguments() { return m_arguments; }
-    
-    public String getMethodReturn() { return m_return; }
-    
+
+    public String getMethodName() {
+        return m_name;
+    }
+
+    public String[] getMethodArguments() {
+        return m_arguments;
+    }
+
+    public String getMethodReturn() {
+        return m_return;
+    }
+
     /**
      * Get the method unique identifier. For internal usage only.
      * @return the method identifier.
      */
     public String getMethodIdentifier() {
-        String id = m_name;
+        StringBuffer identifier = new StringBuffer(m_name);
         for (int i = 0; i < m_arguments.length; i++) {
-            String cn = m_arguments[i];
-            if (cn.endsWith("[]")) {
-                cn = cn.replace('[', '$');
-                cn = cn.substring(0, cn.length() - 1);
+            String arg = m_arguments[i];
+            identifier.append('$');
+            if (arg.endsWith("[]")) {
+                arg = arg.substring(0, arg.length() - 2);
+                identifier.append(arg.replace('.', '_'));
+                identifier.append("__"); // Replace [] by __
+            } else {
+                identifier.append(arg.replace('.', '_'));
             }
-            cn = cn.replace('.', '_');
-            id += cn;
         }
-        return id;
+        return identifier.toString();
+    }
+
+    /**
+     * Compute the method id for the given method. 
+     * @param method : Method object.
+     * @return the method id.
+     */
+    public static String computeMethodId(Method method) {
+        StringBuffer identifier = new StringBuffer(method.getName());
+        Class[] args = method.getParameterTypes();
+        for (int i = 0; i < args.length; i++) {
+            identifier.append('$'); // Argument separator.
+            if (args[i].isArray()) {
+                if (args[i].getComponentType().isPrimitive()) {
+                    // Primitive array
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else {
+                    // Object array
+                    identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
+                }
+                identifier.append("__"); // Add __ (array)
+            } else {
+                if (args[i].isPrimitive()) {
+                    // Primitive type
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i]));
+                } else {
+                    // Object type
+                    identifier.append(args[i].getName().replace('.', '_')); // Replace '.' by '_'
+                }
+            }
+        }
+        return identifier.toString();
     }
 
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
index 08ceccb..e1597a3 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
@@ -18,7 +18,7 @@
  */
 package org.apache.felix.ipojo.parser;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.StringTokenizer;
 
@@ -27,7 +27,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ParseUtils {
+public final class ParseUtils {
 
     /**
      * Parse the string form of an array as {a, b, c}.
@@ -37,18 +37,13 @@
      */
     public static String[] parseArrays(String str) {
         // Remove { and }
-        if (str.startsWith("{") && str.endsWith("}")) {
-            String m = str.substring(1, str.length() - 1);
+        if (str.charAt(0) == '{' && str.charAt(str.length() - 1) == '}') {
+            String internal = (str.substring(1, str.length() - 1)).trim();
             // Check empty array
-            m = m.trim();
-            if (m.length() == 0) {
+            if (internal.length() == 0) {
                 return new String[0];
             }
-            String[] values = split(m, ",");
-            for (int i = 0; i < values.length; i++) {
-                values[i] = values[i].trim();
-            }
-            return values;
+            return split(internal, ",");
         } else {
             return new String[] { str };
         }
@@ -61,40 +56,24 @@
      * @return the resulting string array
      */
     public static List parseArraysAsList(String str) {
-        List result = new ArrayList();
-        // Remove { and }
-        if (str.startsWith("{") && str.endsWith("}")) {
-            String m = str.substring(1, str.length() - 1);
-            // Check empty array
-            m = m.trim();
-            if (m.length() == 0) {
-                return result;
-            }
-            String[] values = split(m, ",");
-            for (int i = 0; i < values.length; i++) {
-                result.add(values[i].trim());
-            }
-            return result;
-        } else {
-            result.add(str);
-            return result;
-        }
+        return Arrays.asList(parseArrays(str));
     }
     
     /**
      * Split method. 
      * This method is equivalent of the String.split in java 1.4
+     * The result array contains 'trimmed' String
      * @param toSplit : String to split
      * @param separator : separator
      * @return the token array 
      */
     public static String[] split(String toSplit, String separator) {
-        StringTokenizer st = new StringTokenizer(toSplit, separator);
-        String[] result = new String[st.countTokens()];
-        int i = 0;
-        while (st.hasMoreElements()) {
-            result[i] = st.nextToken();
-            i++;
+        StringTokenizer tokenizer = new StringTokenizer(toSplit, separator);
+        String[] result = new String[tokenizer.countTokens()];
+        int index = 0;
+        while (tokenizer.hasMoreElements()) {
+            result[index] = tokenizer.nextToken().trim();
+            index++;
         }
         return result;
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
similarity index 82%
rename from ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
rename to ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
index 3d08854..ee8c6fc 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ManipulationMetadata.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
@@ -26,7 +26,7 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class ManipulationMetadata {
+public class PojoMetadata {
     
     /**
      * List of implemented interfaces.
@@ -55,21 +55,21 @@
      * parsing manipulation metadata.
      * @param metadata : component type metadata
      */
-    public ManipulationMetadata(Element metadata) {
+    public PojoMetadata(Element metadata) {
         Element manip = metadata.getElements("manipulation", "")[0];
         m_super = manip.getAttribute("super");
         Element[] fields = manip.getElements("field");
-        for (int i = 0; i < fields.length; i++) {
-            FieldMetadata fm = new FieldMetadata(fields[i]);
-            addField(fm);
+        for (int i = 0; fields != null && i < fields.length; i++) {
+            FieldMetadata field = new FieldMetadata(fields[i]);
+            addField(field);
         }
         Element[] methods = manip.getElements("method");
-        for (int i = 0; i < methods.length; i++) {
-            MethodMetadata fm = new MethodMetadata(methods[i]);
-            addMethod(fm);
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            MethodMetadata method = new MethodMetadata(methods[i]);
+            addMethod(method);
         }
         Element[] itfs = manip.getElements("interface");
-        for (int i = 0; i < itfs.length; i++) {
+        for (int i = 0; itfs != null && i < itfs.length; i++) {
             addInterface(itfs[i].getAttribute("name"));
         }
     }
@@ -167,13 +167,13 @@
     public MethodMetadata getMethod(String name, String[] types) {
         for (int i = 0; i < m_methods.length; i++) {
             if (m_methods[i].getMethodName().equalsIgnoreCase(name) && m_methods[i].getMethodArguments().length == types.length) {
-                boolean ok = true;
-                for (int j = 0; ok && j < types.length; j++) {
-                    if (! types[j].equals(m_methods[i].getMethodArguments()[j])) {
-                        ok = false;
+                int argIndex = 0;
+                for (; argIndex < types.length; argIndex++) {
+                    if (! types[argIndex].equals(m_methods[i].getMethodArguments()[argIndex])) {
+                        break;
                     }
                 }
-                if (ok) { return m_methods[i]; }
+                if (argIndex == types.length) { return m_methods[i]; } // No mismatch detected.
             }
         }
         return null;
@@ -181,11 +181,11 @@
         
      /**
       * Add a method to the list.
-     * @param mm : Method Metadata to add.
+     * @param method : Method Metadata to add.
      */
-    private void addMethod(MethodMetadata mm) {
+    private void addMethod(MethodMetadata method) {
         for (int i = 0; (m_methods != null) && (i < m_methods.length); i++) {
-            if (m_methods[i] == mm) {
+            if (m_methods[i] == method) {
                 return;
             }
         }
@@ -193,20 +193,20 @@
         if (m_methods.length > 0) {
             MethodMetadata[] newInstances = new MethodMetadata[m_methods.length + 1];
             System.arraycopy(m_methods, 0, newInstances, 0, m_methods.length);
-            newInstances[m_methods.length] = mm;
+            newInstances[m_methods.length] = method;
             m_methods = newInstances;
         } else {
-            m_methods = new MethodMetadata[] { mm };
+            m_methods = new MethodMetadata[] { method };
         }
     }
         
      /**
       * Add a field to the list.
-     * @param mm : the Field Metadata to add.
+     * @param field : the Field Metadata to add.
      */
-    private void addField(FieldMetadata mm) {
+    private void addField(FieldMetadata field) {
         for (int i = 0; (m_fields != null) && (i < m_fields.length); i++) {
-            if (m_fields[i] == mm) {
+            if (m_fields[i] == field) {
                 return;
             }
         }
@@ -214,20 +214,20 @@
         if (m_fields.length > 0) {
             FieldMetadata[] newInstances = new FieldMetadata[m_fields.length + 1];
             System.arraycopy(m_fields, 0, newInstances, 0, m_fields.length);
-            newInstances[m_fields.length] = mm;
+            newInstances[m_fields.length] = field;
             m_fields = newInstances;
         } else {
-            m_fields = new FieldMetadata[] { mm };
+            m_fields = new FieldMetadata[] { field };
         }
     }
         
     /**
      * Add the interface to the list.
-     * @param mm : the interface name to add.
+     * @param itf : the interface name to add.
      */
-    private void addInterface(String mm) {
+    private void addInterface(String itf) {
         for (int i = 0; (m_interfaces != null) && (i < m_interfaces.length); i++) {
-            if (m_interfaces[i] == mm) {
+            if (m_interfaces[i] == itf) {
                 return;
             }
         }
@@ -235,10 +235,10 @@
         if (m_interfaces.length > 0) {
             String[] newInstances = new String[m_interfaces.length + 1];
             System.arraycopy(m_interfaces, 0, newInstances, 0, m_interfaces.length);
-            newInstances[m_interfaces.length] = mm;
+            newInstances[m_interfaces.length] = itf;
             m_interfaces = newInstances;
         } else {
-            m_interfaces = new String[] { mm };
+            m_interfaces = new String[] { itf };
         }
     }
 
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
index f19373c..a17326d 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -22,15 +22,15 @@
 import java.lang.reflect.Method;
 
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.parser.FieldMetadata;
 import org.apache.felix.ipojo.parser.MethodMetadata;
 
 /**
  * A callback allows calling a method on the component instances.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Callback {
-    
+
     /**
      * Method object.
      */
@@ -50,7 +50,7 @@
      * Reference on the instance manager.
      */
     private InstanceManager m_manager;
-    
+
     /**
      * Argument classes.
      */
@@ -58,193 +58,112 @@
 
     /**
      * Callback constructor.
-     * 
      * @param method : the name of the method to call
      * @param args : argument type name
      * @param isStatic : is the method a static method
-     * @param im : the instance manager of the component containing the method
+     * @param manager : the instance manager of the component containing the method
      */
-    public Callback(String method, String[] args, boolean isStatic, InstanceManager im) {
+    public Callback(String method, String[] args, boolean isStatic, InstanceManager manager) {
         m_method = method;
         m_isStatic = isStatic;
-        m_manager = im;
+        m_manager = manager;
         if (args != null) {
-            m_args = new String[args.length];
-            for (int i = 0; i < args.length; i++) {
-                // Primitive Array 
-                if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
-                    String arr = "";
-                    for (int j = 0; j < args[i].length(); j++) {
-                        if (args[i].charAt(j) == '[') { arr += '['; }
-                    }
-                    int index = args[i].indexOf('[');
-                    m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
-                }
-                // Non-Primitive Array 
-                if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
-                    String arr = "";
-                    for (int j = 0; j < args[i].length(); j++) {
-                        if (args[i].charAt(j) == '[') { arr += '['; }
-                    }
-                    int index = args[i].indexOf('[');
-                    m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
-                }
-                // Simple type 
-                if (!args[i].endsWith("[]")) {
-                    m_args[i] = args[i];
-                }
-            }
+            computeArguments(args);
         }
-        
     }
-    
+
     /**
      * Callback constructor.
-     * 
      * @param method : the name of the method to call
      * @param args : argument classes
      * @param isStatic : is the method a static method
-     * @param im : the instance manager of the component containing the method
+     * @param manager : the instance manager of the component containing the method
      */
-    public Callback(String method, Class[] args, boolean isStatic, InstanceManager im) {
+    public Callback(String method, Class[] args, boolean isStatic, InstanceManager manager) {
         m_method = method;
         m_isStatic = isStatic;
-        m_manager = im;
+        m_manager = manager;
         m_args = new String[args.length];
         for (int i = 0; i < args.length; i++) {
             m_args[i] = args[i].getName();
         }
     }
-    
+
     /**
      * Constructor.
-     * @param mm : Method Metadata obtain form manipulation metadata.
-     * @param im : instance manager.
+     * @param method : Method Metadata obtain form manipulation metadata.
+     * @param manager : instance manager.
      */
-    public Callback(MethodMetadata mm, InstanceManager im) {
+    public Callback(MethodMetadata method, InstanceManager manager) {
         m_isStatic = false;
-        m_method = mm.getMethodName();
-        m_manager = im;
-        String[] args = mm.getMethodArguments();
+        m_method = method.getMethodName();
+        m_manager = manager;
+        computeArguments(method.getMethodArguments());
+    }
+
+    /**
+     * Compute arguments of the method.
+     * @param args : arguments of the method.
+     */
+    private void computeArguments(String[] args) {
         m_args = new String[args.length];
         for (int i = 0; i < args.length; i++) {
-            // Primitive Array 
-            if (args[i].endsWith("[]") && args[i].indexOf(".") == -1) {
-                String arr = "";
-                for (int j = 0; j < args[i].length(); j++) {
-                    if (args[i].charAt(j) == '[') { arr += '['; }
-                }
-                int index = args[i].indexOf('[');
-                m_args[i] = arr + getInternalPrimitiveType(args[i].substring(0, index));
-            }
-            // Non-Primitive Array 
-            if (args[i].endsWith("[]") && args[i].indexOf(".") != -1) {
-                String arr = "";
-                for (int j = 0; j < args[i].length(); j++) {
-                    if (args[i].charAt(j) == '[') { arr += '['; }
-                }
-                int index = args[i].indexOf('[');
-                m_args[i] = arr + "L" + args[i].substring(0, index) + ";";
-            }
-            // Simple type 
-            if (!args[i].endsWith("[]")) {
-                m_args[i] = args[i];
-            }
+            m_args[i] = FieldMetadata.getReflectionType(args[i]);
         }
     }
 
     /**
-     * Get the internal notation for primitive type.
-     * @param string : Stringform of the type
-     * @return the internal notation or null if not found
+     * Search the looked method in the given method arrays.
+     * @param methods : method array in which we need to look
+     * @return the method object or null if not found
      */
-    private String getInternalPrimitiveType(String string) {
-        if (string.equalsIgnoreCase("boolean")) {
-            return "Z";
-        }
-        if (string.equalsIgnoreCase("char")) {
-            return "C";
-        }
-        if (string.equalsIgnoreCase("byte")) {
-            return "B";
-        }
-        if (string.equalsIgnoreCase("short")) {
-            return "S";
-        }
-        if (string.equalsIgnoreCase("int")) {
-            return "I";
-        }
-        if (string.equalsIgnoreCase("float")) {
-            return "F";
-        }
-        if (string.equalsIgnoreCase("long")) {
-            return "J";
-        }
-        if (string.equalsIgnoreCase("double")) {
-            return "D";
-        }
-        return null;
-    }
-    
-    /**
-     * Search the method object in the POJO by analyzing present method.
-     * The name of the method and the argument type are checked.
-     */
-    protected void searchMethod() {
-        Method[] methods = m_manager.getClazz().getDeclaredMethods();
-        for (int i = 0; m_methodObj == null && i < methods.length; i++) {
+    private Method searchMethodInMethodArray(Method[] methods) {
+        for (int i = 0; i < methods.length; i++) {
             // First check the method name
             if (methods[i].getName().equals(m_method)) {
                 // Check arguments
                 Class[] clazzes = methods[i].getParameterTypes();
                 if (clazzes.length == m_args.length) { // Test size to avoid useless loop
-                    boolean ok = true;
-                    for (int j = 0; ok && j < m_args.length; j++) {
-                        if (!m_args[j].equals(clazzes[j].getName())) {
-                            ok = false;
+                    int argIndex = 0;
+                    for (; argIndex < m_args.length; argIndex++) {
+                        if (!m_args[argIndex].equals(clazzes[argIndex].getName())) {
+                            break;
                         }
                     }
-                    if (ok) {
-                        m_methodObj = methods[i]; // It is the looked method.
-                    } 
+                    if (argIndex == m_args.length) { // No mismatch detected. 
+                        return methods[i]; // It is the looked method.
+                    }
                 }
+            }
+        }
+        return null;
+    }
 
-            }
-        }
-        
-        if (m_methodObj == null) { //look at parent classes
+    /**
+     * Search the method object in the POJO by analyzing present method. The name of the method and the argument type are checked.
+     * @throws NoSuchMethodException : occurs when the method cannot be found either in the pojo class either in parent classes.
+     */
+    protected void searchMethod() throws NoSuchMethodException {
+        Method[] methods = m_manager.getClazz().getDeclaredMethods();
+        m_methodObj = searchMethodInMethodArray(methods);
+
+        if (m_methodObj == null) { // look at parent classes
             methods = m_manager.getClazz().getMethods();
-            for (int i = 0; m_methodObj == null && i < methods.length; i++) {
-                // First check the method name
-                if (methods[i].getName().equals(m_method)) {
-                    // Check arguments
-                    Class[] clazzes = methods[i].getParameterTypes();
-                    if (clazzes.length == m_args.length) { // Test size to avoid useless loop
-                        boolean ok = true;
-                        for (int j = 0; ok && j < m_args.length; j++) {
-                            if (!m_args[j].equals(clazzes[j].getName())) {
-                                ok = false;
-                            }
-                        }
-                        if (ok) {
-                            m_methodObj = methods[i]; // It is the looked method.
-                        } 
-                    }
-                }
-            }
+            m_methodObj = searchMethodInMethodArray(methods);
         }
-        
+
         if (m_methodObj == null) {
-            m_manager.getFactory().getLogger().log(Logger.ERROR, "The method " + m_method + " cannot be called : method not found");
-            m_manager.stop();
+            throw new NoSuchMethodException(m_method);
         } else {
-            m_methodObj.setAccessible(true);
+            if (! m_methodObj.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
         }
     }
 
     /**
      * Call the method.
-     * 
      * @return the result of the invocation, null for void method, the last result for multi-object instance
      * @throws NoSuchMethodException : Method is not found in the class
      * @throws InvocationTargetException : The method is not static
@@ -256,7 +175,6 @@
 
     /**
      * Call the current callback method on the instance given in parameter.
-     * 
      * @param instance : instance on which call the callback
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the method was not found
@@ -269,19 +187,17 @@
 
     /**
      * Call the callback on the method with the argument given in parameter.
-     * 
      * @param arg : the parameters
      * @return the result of the invocation, null for void method, the last result for multi-object instance
      * @throws NoSuchMethodException : the callback method is not found
      * @throws IllegalAccessException : the callback method cannot be called
-     * @throws InvocationTargetException : an error occurs inside the called
-     * method
+     * @throws InvocationTargetException : an error occurs inside the called method
      */
     public Object call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (m_methodObj == null) {
             searchMethod();
         }
-        
+
         if (m_isStatic) {
             return m_methodObj.invoke(null, arg);
         } else {
@@ -291,35 +207,32 @@
             if (m_manager.getPojoObjects() == null) {
                 return m_methodObj.invoke(m_manager.getPojoObject(), arg);
             } else {
-                Object r = null;
+                Object newObject = null;
                 for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
-                    r = m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
+                    newObject = m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
                 }
-                return r;
+                return newObject;
             }
         }
     }
 
     /**
-     * Call the callback on the method with the argument given in parameter and
-     * with the arguments given in parameter too.
-     * 
+     * Call the callback on the method with the argument given in parameter and with the arguments given in parameter too.
      * @param instance : instance on which call the callback
      * @param arg : the argument array
      * @return the result of the invocation, null for void method
      * @throws NoSuchMethodException : the callback method is not found
      * @throws IllegalAccessException : the callback method cannot be called
-     * @throws InvocationTargetException : an error occurs inside the called
-     * method
+     * @throws InvocationTargetException : an error occurs inside the called method
      */
     public Object call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         if (m_methodObj == null) {
             searchMethod();
         }
-        
+
         return m_methodObj.invoke(instance, arg);
     }
-    
+
     public String getMethod() {
         return m_method;
     }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
new file mode 100644
index 0000000..d644805
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
@@ -0,0 +1,792 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.util;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.List;

+

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.metadata.Element;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Abstract dependency model. This class is the parent class of every service dependency. It manages the most part of dependency management. This

+ * class creates an insterface between the service tracker and the concrete dependency.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public abstract class DependencyModel implements TrackerCustomizer {

+

+    /**

+     * Dependency state : BROKEN. A broken dependency cannot be fulfilled anymore. The dependency becomes broken when a used service disappears in the

+     * static binding policy.

+     */

+    public static final int BROKEN = -1;

+

+    /**

+     * Dependency state : UNRESOLVED. A dependency is unresolved if the dependency is not valid and no service providers are available.

+     */

+    public static final int UNRESOLVED = 0;

+

+    /**

+     * Dependency state : RESOLVED. A dependency is resolved if the dependency is optional or at least one provider is available.

+     */

+    public static final int RESOLVED = 1;

+

+    /**

+     * Binding policy : Dynamic. In this policy, services can appears and departs without special treatment.

+     */

+    public static final int DYNAMIC_BINDING_POLICY = 0;

+

+    /**

+     * Binding policy : Static. Once a service is used, if this service disappears the dependency becomes BROKEN. The instance needs to be recreated.

+     */

+    public static final int STATIC_BINDING_POLICY = 1;

+

+    /**

+     * Binding policy : Dynamic-Priority. In this policy, services can appears and departs. However, once a service with a highest ranking (according

+     * to the used comparator) appears, this new service is re-injected.

+     */

+    public static final int DYNAMIC_PRIORITY_BINDING_POLICY = 2;

+

+    /**

+     * Does the dependency bind several providers ?

+     */

+    private boolean m_aggregate;

+

+    /**

+     * Is the dependency optional ?

+     */

+    private boolean m_optional;

+

+    /**

+     * Required specification. Cannot change once set.

+     */

+    private Class m_specification;

+

+    /**

+     * Comparator to sort service references.

+     */

+    private Comparator m_comparator;

+

+    /**

+     * LDAP filter object selecting service references form the set of providers providing the required specification.

+     */

+    private Filter m_filter;

+

+    /**

+     * Bundle context used by the dependency. (could be a service context).

+     */

+    private BundleContext m_context;

+

+    /**

+     * Listener object on which invoking the validate and invalidate methods.

+     */

+    private final DependencyStateListener m_listener;

+

+    /**

+     * Actual state of the dependency.

+     */

+    private int m_state;

+

+    /**

+     * Binding policy of the dependency.

+     */

+    private int m_policy = DYNAMIC_BINDING_POLICY; // Is notas we have to handler policy change in a future version.

+

+    /**

+     * Service tracker used by this dependency.

+     */

+    private Tracker m_tracker;

+

+    /**

+     * List of matching service references. This list is a subset of tracked references. This set is compute according to the filter and the match

+     * method.

+     */

+    private final List m_matchingRefs = new ArrayList();

+

+    /**

+     * Constructor.

+     * @param specification : required specification

+     * @param aggregate : is the dependency aggregate ?

+     * @param optional : is the dependency optional ?

+     * @param filter : LDAP filter

+     * @param comparator : comparator object to sort references

+     * @param policy : binding policy

+     * @param context : bundle context (or service context)

+     * @param listener : dependency lifecycle listener to notify from dependency state changes.

+     */

+    public DependencyModel(Class specification, boolean aggregate, boolean optional, Filter filter, Comparator comparator, int policy,

+            BundleContext context, DependencyStateListener listener) {

+        m_specification = specification;

+        m_aggregate = aggregate;

+        m_optional = optional;

+        m_filter = filter;

+        m_comparator = comparator;

+        m_context = context;

+        m_policy = policy;

+        // If the dynamic priority policy is chosen, and we have no comparator, fix it to OSGi standard service reference comparator.

+        if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_comparator == null) {

+            m_comparator = new ServiceReferenceRankingComparator();

+        }

+        m_state = UNRESOLVED;

+        m_listener = listener;

+    }

+

+    /**

+     * Open the tracking.

+     */

+    public void start() {

+        m_tracker = new Tracker(m_context, m_specification.getName(), this);

+        m_tracker.open();

+        computeDependencyState();

+    }

+

+    /**

+     * Close the tracking.

+     */

+    public void stop() {

+        if (m_tracker != null) {

+            m_tracker.close();

+            m_tracker = null;

+        }

+        m_state = UNRESOLVED;

+    }

+

+    /**

+     * Is the reference set frozen (cannot change anymore) ? This method must be override by concrete dependency to support the static binding policy.

+     * This method is just used by default. The method must always return false for non-static dependency.

+     * @return true if the reference set is frozen.

+     */

+    public boolean isFrozen() {

+        return false;

+    }

+

+    /**

+     * Does the service reference match ? This method must be override by concrete dependency if they need to advanced testing on service reference

+     * (that cannot be express in the LDAP filter). By default this method return true.

+     * @param ref : tested reference.

+     * @return true

+     */

+    public boolean match(ServiceReference ref) {

+        return true;

+    }

+

+    /**

+     * Compute the actual dependency state.

+     */

+    private void computeDependencyState() {

+        if (m_state == BROKEN) { return; } // The dependency is broken ...

+

+        boolean mustCallValidate = false;

+        boolean mustCallInvalidate = false;

+        synchronized (this) {

+            if (m_optional || !m_matchingRefs.isEmpty()) {

+                // The dependency is valid

+                if (m_state == UNRESOLVED) {

+                    m_state = RESOLVED;

+                    mustCallValidate = true;

+                }

+            } else {

+                // The dependency is invalid

+                if (m_state == RESOLVED) {

+                    m_state = UNRESOLVED;

+                    mustCallInvalidate = true;

+                }

+            }

+        }

+

+        // Invoke callback in a non-synchronized region

+        if (mustCallInvalidate) {

+            invalidate();

+        } else if (mustCallValidate) {

+            validate();

+        }

+

+    }

+

+    /**

+     * Service tracker adding service callback. We accept the service only if we aren't broken or frozen.

+     * @param ref : the new dependency.

+     * @return true if the reference must be tracked.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+     */

+    public boolean addingService(ServiceReference ref) {

+        return !((m_state == BROKEN) || isFrozen());

+    }

+

+    /**

+     * Service Tracker added service callback. If the service matches, manage the arrival.

+     * @param ref : new references.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

+     */

+    public void addedService(ServiceReference ref) {

+        if ((m_filter == null || m_filter.match(ref)) && match(ref)) {

+            manageArrival(ref);

+        }

+        // Do not store the service if it doesn't match.

+    }

+

+    /**

+     * Manage the arrival of a new service reference. The reference is valid and match the filter and the match method. This method has different

+     * behavior according to the binding policy.

+     * @param ref : the new reference

+     */

+    private void manageArrival(ServiceReference ref) {

+

+        // Create a local copy of the state and of the list size.

+        int state = m_state;

+        int size;

+

+        synchronized (this) {

+            m_matchingRefs.add(ref);

+

+            // Sort the collection if needed.

+            if (m_comparator != null) {

+                Collections.sort(m_matchingRefs, m_comparator);

+            }

+

+            size = m_matchingRefs.size();

+        }

+

+        if (m_aggregate) {

+            onServiceArrival(ref); // Always notify the arrival for aggregate dependencies.

+            if (state == UNRESOLVED) { // If we was unresolved, try to validate the dependency.

+                computeDependencyState();

+            }

+        } else { // We are not aggregate.

+            if (size == 1) {

+                onServiceArrival(ref); // It is the first service, so notify.

+                computeDependencyState();

+            } else {

+                // In the case of a dynamic priority binding, we have to test if we have to update the bound reference

+                if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_matchingRefs.get(0) == ref) {

+                    // We are sure that we have at least two references, so if the highest ranked references (first one) is the new received

+                    // references,

+                    // we have to unbind the used one and to bind the the new one.

+                    onServiceDeparture((ServiceReference) m_matchingRefs.get(1));

+                    onServiceArrival(ref);

+                }

+            }

+        }

+        // Ignore others cases

+    }

+

+    /**

+     * Service tracker removed service callback. A service goes away. The depart need to be managed only if the reference was used.

+     * @param ref : leaving service reference

+     * @param arg1 : service object if the service was get

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void removedService(ServiceReference ref, Object arg1) {

+        if (m_matchingRefs.contains(ref)) {

+            manageDeparture(ref, arg1);

+        }

+    }

+

+    /**

+     * Manage the departure of a used service.

+     * @param ref : leaving service reference

+     * @param obj : service object if the service was get

+     */

+    private void manageDeparture(ServiceReference ref, Object obj) {

+        // If we already get this service and the binding policy is static, the dependency becomes broken

+        if (isFrozen() && obj != null) {

+            if (m_state != BROKEN) {

+                m_state = BROKEN;

+                invalidate();

+            }

+        } else {

+            synchronized (this) {

+                m_matchingRefs.remove(ref);

+            }

+            if (obj == null) {

+                computeDependencyState(); // check if the dependency stills valid.

+            } else {

+                onServiceDeparture(ref);

+                ServiceReference newRef = getServiceReference();

+                if (newRef == null) { // Check if there is another provider.

+                    computeDependencyState(); // no more references.

+                } else {

+                    if (!m_aggregate) {

+                        onServiceArrival(newRef); // Injecting the new service reference for non aggregate dependencies.

+                    }

+                }

+            }

+        }

+

+    }

+

+    /**

+     * Service tracker modified service callback. This method must handle if the modified service should be considered as a depart or an arrival.

+     * According to the dependency filter, a service can now match or can no match anymore.

+     * @param ref : modified reference

+     * @param arg1 : service object if already get.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void modifiedService(ServiceReference ref, Object arg1) {

+        if (m_matchingRefs.contains(ref)) {

+            // It's a used service. Check if the service always match.

+            if (!(m_filter == null || m_filter.match(ref)) && match(ref)) {

+                // The service does not match anymore. Call removedService.

+                manageDeparture(ref, arg1);

+            } else {

+                onServiceModification(ref);

+            }

+        } else {

+            // The service was not used. Check if it matches.

+            if ((m_filter == null || m_filter.match(ref)) && match(ref)) {

+                manageArrival(ref);

+            }

+            // Else, the service does not match.

+        }

+    }

+

+    /**

+     * Get the next matching service reference.

+     * @return null if no more provider is available, else return the first reference from the matching set.

+     */

+    public ServiceReference getServiceReference() {

+        synchronized (this) {

+            if (m_matchingRefs.isEmpty()) {

+                return null;

+            } else {

+                return (ServiceReference) m_matchingRefs.get(0);

+            }

+        }

+    }

+

+    /**

+     * Get matching service references.

+     * @return the sorted (if a comparator is used) array of matching service references, null if no references are available.

+     */

+    public ServiceReference[] getServiceReferences() {

+        synchronized (this) {

+            if (m_matchingRefs.isEmpty()) { return null; }

+            return (ServiceReference[]) m_matchingRefs.toArray(new ServiceReference[m_matchingRefs.size()]);

+        }

+    }

+

+    /**

+     * Get the list of currently used service references.

+     * @return the list of used reference (according to the service tracker).

+     */

+    public List getUsedServiceReferences() {

+        synchronized (this) {

+            // The list must confront actual matching services with already get services from the tracker.

+

+            int size = m_matchingRefs.size();

+            List usedByTracker = m_tracker.getUsedServiceReferences();

+            if (size == 0 || usedByTracker == null) { return null; }

+

+            List list = new ArrayList(1);

+            for (int i = 0; i < size; i++) {

+                if (usedByTracker.contains(m_matchingRefs.get(i))) {

+                    list.add(m_matchingRefs.get(i)); // Add the service in the list.

+                    if (!isAggregate()) { // IF we are not multiple, return the list when the first element is found.

+                        return list;

+                    }

+                }

+            }

+

+            return list;

+        }

+    }

+

+    /**

+     * Get the number of actual matching references.

+     * @return the number of matching references

+     */

+    public int getSize() {

+        return m_matchingRefs.size();

+    }

+

+    /**

+     * Concrete dependency callback. This method is called when a new service need to be re-injected in the underlying concrete dependency.

+     * @param ref : service reference to inject.

+     */

+    public abstract void onServiceArrival(ServiceReference ref);

+

+    /**

+     * Concrete dependency callback. This method is called when a used service (already injected) is leaving.

+     * @param ref : the leaving service reference.

+     */

+    public abstract void onServiceDeparture(ServiceReference ref);

+

+    /**

+     * This method can be override by the concrete dependency to be notified of service modification. This modification is not an arrival or a

+     * departure.

+     * @param ref : modified service reference.

+     */

+    public void onServiceModification(ServiceReference ref) {

+        // Do nothing by default.

+    }

+

+    /**

+     * Concrete dependency callback. This method is called when the dependency is reconfigured and when this reconfiguration implies changes on the

+     * matching service set ( and by the way on the injected service).

+     * @param departs : service leaving the matching set.

+     * @param arrivals : service arriving in the matching set.

+     */

+    public abstract void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals);

+

+    /**

+     * Call the listener callback to notify the new state of the current dependency.

+     */

+    private void invalidate() {

+        m_listener.invalidate(this);

+    }

+

+    /**

+     * Call the listener callback to notify the new state of the current dependency.

+     */

+    private void validate() {

+        m_listener.validate(this);

+    }

+

+    /**

+     * Get the actual state of the dependency.

+     * @return : the state of the dependency.

+     */

+    public int getState() {

+        return m_state;

+    }

+

+    /**

+     * Get the tracked specification.

+     * @return the Class object tracked by the dependency.

+     */

+    public Class getSpecification() {

+        return m_specification;

+    }

+

+    /**

+     * Set the required specification of this service dependency. This operation is not supported if the dependency tracking has already begun.

+     * @param specification : required specification.

+     */

+    public void setSpecification(Class specification) {

+        if (m_tracker == null) {

+            m_specification = specification;

+        } else {

+            throw new UnsupportedOperationException("Dynamic specification change is not yet supported");

+        }

+    }

+

+    /**

+     * Set the filter of the dependency. This method recompute the matching set and call the onDependencyReconfiguration callback.

+     * @param filter : new LDAP filter.

+     */

+    public void setFilter(Filter filter) { //NOPMD

+        m_filter = filter;

+        if (m_tracker != null) { // Tracking started ...

+            List toRemove = new ArrayList();

+            List toAdd = new ArrayList();

+            ServiceReference usedRef = null;

+            synchronized (this) {

+

+                // Store the used service references.

+                if (!m_aggregate && !m_matchingRefs.isEmpty()) {

+                    usedRef = (ServiceReference) m_matchingRefs.get(0);

+                }

+

+                // Get actually all tracked references.

+                ServiceReference[] refs = m_tracker.getServiceReferences();

+

+                if (refs == null) {

+                    for (int j = 0; j < m_matchingRefs.size(); j++) {

+                        // All references need to be removed.

+                        toRemove.add(m_matchingRefs.get(j));

+                    }

+                    // No more matching dependency. Clear the matching reference set.

+                    m_matchingRefs.clear();

+                } else {

+                    // Compute matching services.

+                    List matching = new ArrayList();

+                    for (int i = 0; i < refs.length; i++) {

+                        if (m_filter == null || m_filter.match(refs[i]) && match(refs[i])) {

+                            matching.add(refs[i]);

+                        }

+                    }

+                    // Now compare with used services.

+                    for (int j = 0; j < m_matchingRefs.size(); j++) {

+                        ServiceReference ref = (ServiceReference) m_matchingRefs.get(j);

+                        // Check if the reference is inside the matching list:

+                        if (!matching.contains(ref)) {

+                            // The reference should be removed

+                            toRemove.add(ref);

+                        }

+                    }

+

+                    // Then remove services which do no more match.

+                    m_matchingRefs.removeAll(toRemove);

+

+                    // Then, add new matching services.

+

+                    for (int k = 0; k < matching.size(); k++) {

+                        if (!m_matchingRefs.contains(matching.get(k))) {

+                            m_matchingRefs.add(matching.get(k));

+                            toAdd.add(matching.get(k));

+                        }

+                    }

+

+                    // Sort the collections if needed.

+                    if (m_comparator != null) {

+                        Collections.sort(m_matchingRefs, m_comparator);

+                        Collections.sort(toAdd, m_comparator);

+                        Collections.sort(toRemove, m_comparator);

+                    }

+

+                }

+            }

+

+            // Call the callback outside the sync bloc.

+            if (m_aggregate) {

+                ServiceReference[] rem = null;

+                ServiceReference[] add = null;

+                if (!toAdd.isEmpty()) {

+                    add = (ServiceReference[]) toAdd.toArray(new ServiceReference[toAdd.size()]);

+                }

+                if (!toRemove.isEmpty()) {

+                    rem = (ServiceReference[]) toRemove.toArray(new ServiceReference[toRemove.size()]);

+                }

+                if (rem != null || add != null) { // Notify the change only when a change is made on the matching reference list.

+                    onDependencyReconfiguration(rem, add);

+                }

+            } else {

+                // Create a local copy to avoid un-sync reference list access.

+                int size;

+                ServiceReference newRef = null;

+                synchronized (m_matchingRefs) {

+                    size = m_matchingRefs.size();

+                    if (size > 0) {

+                        newRef = (ServiceReference) m_matchingRefs.get(0);

+                    }

+                }

+                // Non aggregate case.

+                // If the used reference was not null

+                if (usedRef == null) {

+                    // The used ref was null,

+                    if (size > 0) {

+                        onDependencyReconfiguration(null, new ServiceReference[] { newRef });

+                    } // Don't notify the change, if the set is not touched by the reconfiguration.

+                } else {

+                    // If the used ref disappears, inject a new service if available, else reinject null.

+                    if (toRemove.contains(usedRef)) {

+                        // We have to replace the service.

+                        if (size > 0) {

+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });

+                        } else {

+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, null);

+                        }

+                    } else if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && newRef != usedRef) { //NOPMD

+                        // In the case of dynamic-priority, check if the used ref is no more the highest reference

+                        onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });

+                    }

+                }

+            }

+            // Now, compute the new dependency state.

+            computeDependencyState();

+        }

+    }

+

+    /**

+     * Return the dependency filter (String form).

+     * @return the String form of the LDAP filter used by this dependency, null if not set.

+     */

+    public String getFilter() {

+        if (m_filter == null) {

+            return null;

+        } else {

+            return m_filter.toString();

+        }

+    }

+

+    /**

+     * Set the aggregate attribute of the current dependency. If the tracking is open, it will call arrival and departure callbacks.

+     * @param isAggregate : new aggregate attribute value.

+     */

+    public synchronized void setAggregate(boolean isAggregate) {

+        if (m_tracker == null) { // Not started ...

+            m_aggregate = isAggregate;

+        } else {

+            // We become aggregate.

+            if (!m_aggregate && isAggregate) {

+                m_aggregate = true;

+                // Call the callback on all non already injected service.

+                if (m_state == RESOLVED) {

+

+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 is already injected.

+                        onServiceArrival((ServiceReference) m_matchingRefs.get(i));

+                    }

+                }

+            } else if (m_aggregate && !isAggregate) {

+                m_aggregate = false;

+                // We become non-aggregate.

+                if (m_state == RESOLVED) {

+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 stills injected.

+                        onServiceDeparture((ServiceReference) m_matchingRefs.get(i));

+                    }

+                }

+            }

+            // Else, do nothing.

+        }

+    }

+

+    public boolean isAggregate() {

+        return m_aggregate;

+    }

+

+    /**

+     * Set the optionality attribute of the current dependency.

+     * @param isOptional : the new optional attribute value.

+     */

+    public void setOptionality(boolean isOptional) {

+        if (m_tracker == null) { // Not started ...

+            m_optional = isOptional;

+        } else {

+            computeDependencyState();

+        }

+    }

+

+    public boolean isOptional() {

+        return m_optional;

+    }

+

+    /**

+     * Return the used binding policy.

+     * @return the current binding policy.

+     */

+    public int getBindingPolicy() {

+        return m_policy;

+    }

+

+    /**

+     * Set the binding policy. Not yet supported.

+     */

+    public void setBindingPolicy() {

+        throw new UnsupportedOperationException("Binding Policy change is not yet supported");

+        // TODO supporting dynamic policy change.

+    }

+

+    public void setComparator(Comparator cmp) {

+        m_comparator = cmp;

+        // NOTE: the array will be sorted at the next get.

+    }

+

+    /**

+     * Set the bundle context used by this dependency. This operation is not supported if the tracker is already opened.

+     * @param context : bundle context or service context to use

+     */

+    public void setBundleContext(BundleContext context) {

+        if (m_tracker == null) { // Not started ...

+            m_context = context;

+        } else {

+            throw new UnsupportedOperationException("Dynamic bundle (i.e. service) context change is not supported");

+        }

+    }

+

+    /**

+     * Get a service object for the given reference.

+     * @param ref : wanted service reference

+     * @return : the service object attached to the given reference

+     */

+    public Object getService(ServiceReference ref) {

+        return m_tracker.getService(ref);

+    }

+

+    /**

+     * Unget a used service reference.

+     * @param ref : reference to unget.

+     */

+    public void ungetService(ServiceReference ref) {

+        m_tracker.ungetService(ref);

+    }

+

+    /**

+     * Helper method parsing the comparator attribute and returning the comparator object. If the 'comparator' attribute is not set, this method

+     * returns null. If the 'comparator' attribute is set to 'osgi', this method returns the normal OSGi comparator. In other case, it tries to create

+     * an instance of the declared comparator class.

+     * @param dep : Element describing the dependency

+     * @param context : bundle context (to load the comparator class)

+     * @return the comparator object, null if not set.

+     * @throws ConfigurationException the comparator class cannot be load or the comparator cannot be instantiated correctly.

+     */

+    public static Comparator getComparator(Element dep, BundleContext context) throws ConfigurationException {

+        Comparator cmp = null;

+        String comp = dep.getAttribute("comparator");

+        if (comp != null) {

+            if (comp.equalsIgnoreCase("osgi")) {

+                cmp = new ServiceReferenceRankingComparator();

+            } else {

+                try {

+                    Class cla = context.getBundle().loadClass(comp);

+                    cmp = (Comparator) cla.newInstance();

+                } catch (ClassNotFoundException e) {

+                    throw new ConfigurationException("Cannot load a customized comparator : " + e.getMessage());

+                } catch (IllegalAccessException e) {

+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());

+                } catch (InstantiationException e) {

+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());

+                }

+            }

+        }

+        return cmp;

+    }

+

+    /**

+     * Load the given specification class.

+     * @param specification : specification class name to load

+     * @param context : bundle context

+     * @return : the class object for the given specification

+     * @throws ConfigurationException : the class cannot be loaded correctly.

+     */

+    public static Class loadSpecification(String specification, BundleContext context) throws ConfigurationException {

+        Class spec = null;

+        try {

+            spec = context.getBundle().loadClass(specification);

+        } catch (ClassNotFoundException e) {

+            throw new ConfigurationException("A required specification cannot be loaded : " + specification);

+        }

+        return spec;

+    }

+

+    /**

+     * Helper method parsing the binding policy. If the 'policy' attribute is not set in the dependency, the method returns the 'DYNAMIC BINDING

+     * POLICY'. Accepted policy values are : dynamic, dynamic-priority and static.

+     * @param dep : Element describing the dependency

+     * @return : the policy attached to this dependency

+     * @throws ConfigurationException : an unknown biding policy was described.

+     */

+    public static int getPolicy(Element dep) throws ConfigurationException {

+        String policy = dep.getAttribute("policy");

+        if (policy == null || policy.equalsIgnoreCase("dynamic")) {

+            return DYNAMIC_BINDING_POLICY;

+        } else if (policy.equalsIgnoreCase("dynamic-priority")) {

+            return DYNAMIC_PRIORITY_BINDING_POLICY;

+        } else if (policy.equalsIgnoreCase("static")) {

+            return STATIC_BINDING_POLICY;

+        } else {

+            throw new ConfigurationException("Binding policy unknown : " + policy);

+        }

+    }

+

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
new file mode 100644
index 0000000..5131337
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
@@ -0,0 +1,39 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.util;

+

+

+/**

+ * This interface allows a class to be notified of dependency state changes.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public interface DependencyStateListener {

+

+    /**

+     * The given dependency becomes valid.

+     * @param dependency : dependency becoming valid.

+     */

+    void validate(DependencyModel dependency);

+    

+    /**

+     * The given dependency becomes invalid.

+     * @param dependency : dependency becoming invalid.

+     */

+    void invalidate(DependencyModel dependency);

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
index 30a33a2..c8b8c26 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
@@ -28,6 +28,11 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Logger {
+    
+    /**
+     * Ipojo default log level property.
+     */
+    public static final String IPOJO_LOG_LEVEL = "ipojo.log.level";
 
     /**
      * Log Level ERROR.
@@ -67,14 +72,24 @@
     /**
      * Constructor.
      * 
-     * @param bc : bundle context
+     * @param context : bundle context
      * @param name : name of the logger
      * @param level : trace level
      */
-    public Logger(BundleContext bc, String name, int level) {
+    public Logger(BundleContext context, String name, int level) {
         m_name = name;
         m_level = level;
-        m_context = bc;
+        m_context = context;
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param context : bundle context
+     * @param name : name of the logger
+     */
+    public Logger(BundleContext context, String name) {
+        this(context, name, getDefaultLevel(context));
     }
 
     /**
@@ -85,7 +100,7 @@
      */
     public void log(int level, String msg) {
         if (m_level >= level) {
-            dispatch(level, msg, null);
+            dispatch(level, msg);
         }
     }
 
@@ -94,26 +109,21 @@
      * 
      * @param level : level of the message
      * @param msg : message to log
-     * @param ex : exception attached to the message
+     * @param exception : exception attached to the message
      */
-    public void log(int level, String msg, Throwable ex) {
+    public void log(int level, String msg, Throwable exception) {
         if (m_level >= level) {
-            dispatch(level, msg, ex);
+            dispatch(level, msg, exception);
         }
     }
-
+    
     /**
      * Internal log method.
      * 
      * @param level : level of the message.
      * @param msg : message to log
-     * @param ex : exception attached to the message
      */
-    private void dispatch(int level, String msg, Throwable ex) {
-        String s = msg;
-        if (ex != null) {
-            s += " (" + ex.getMessage() + ")";
-        }
+    private void dispatch(int level, String msg) {
         
         ServiceReference ref = m_context.getServiceReference(LogService.class.getName());
         LogService log = null;
@@ -124,35 +134,35 @@
         String message = null;
         switch (level) {
             case DEBUG:
-                message = "[" + m_name + "] DEBUG: " + s;
+                message = "[" + m_name + "] DEBUG: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_DEBUG, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             case ERROR:
-                message = "[" + m_name + "] ERROR: " + s;
+                message = "[" + m_name + "] ERROR: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_ERROR, message);
                 }
-                System.err.println(message);
+                System.err.println(message); //NOPMD
                 break;
             case INFO:
-                message = "[" + m_name + "] INFO: " + s;
+                message = "[" + m_name + "] INFO: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_INFO, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             case WARNING:
-                message = "[" + m_name + "] WARNING: " + s;
+                message = "[" + m_name + "] WARNING: " + msg;
                 if (log != null) {
                     log.log(LogService.LOG_WARNING, message);
                 }
-                System.err.println(message);
+                System.err.println(message); // NOPMD
                 break;
             default:
-                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + s);
+                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); // NOPMD
                 break;
         }
         
@@ -160,4 +170,98 @@
             m_context.ungetService(ref);
         }
     }
+
+    /**
+     * Internal log method.
+     * 
+     * @param level : level of the message.
+     * @param msg : message to log
+     * @param exception : exception attached to the message
+     */
+    private void dispatch(int level, String msg, Throwable exception) {
+        
+        ServiceReference ref = m_context.getServiceReference(LogService.class.getName());
+        LogService log = null;
+        if (ref != null) {
+            log = (LogService) m_context.getService(ref);
+        }
+        
+        String message = null;
+        switch (level) {
+            case DEBUG:
+                message = "[" + m_name + "] DEBUG: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_DEBUG, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(); // NOPMD
+                break;
+            case ERROR:
+                message = "[" + m_name + "] ERROR: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_ERROR, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            case INFO:
+                message = "[" + m_name + "] INFO: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_INFO, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            case WARNING:
+                message = "[" + m_name + "] WARNING: " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_WARNING, message, exception);
+                }
+                System.err.println(message); // NOPMD
+                exception.printStackTrace(System.err); // NOPMD
+                break;
+            default:
+                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); // NOPMD
+                exception.printStackTrace(); // NOPMD
+                break;
+        }
+        
+        if (log != null) {
+            m_context.ungetService(ref);
+        }
+    }
+    
+    /**
+     * Get the default logger level.
+     * The property is searched inside the framework properties, the system properties,
+     * and in the manifest from the given bundle context. By default, set the level to WARNING. 
+     * @param context : bundle context.
+     * @return the default log level.
+     */
+    private static int getDefaultLevel(BundleContext context) {
+        // First check in the framework and in the system properties
+        String level = context.getProperty(IPOJO_LOG_LEVEL);
+        
+        // If null, look in bundle manifest
+        if (level == null) {
+            level = (String) context.getBundle().getHeaders().get(IPOJO_LOG_LEVEL);
+        }
+        
+        if (level != null) {
+            if (level.equalsIgnoreCase("info")) {
+                return INFO;
+            } else if (level.equalsIgnoreCase("debug")) {
+                return DEBUG;
+            } else if (level.equalsIgnoreCase("warning")) {
+                return WARNING;
+            } else if (level.equalsIgnoreCase("error")) {
+                return ERROR;
+            }
+        }
+        
+        // Either l is null, either the specified log level was unknown
+        // Set the default to WARNING
+        return WARNING;
+        
+    }
 }
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
new file mode 100644
index 0000000..948b66b
--- /dev/null
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
@@ -0,0 +1,472 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.util;

+

+import java.lang.reflect.Array;

+import java.lang.reflect.Constructor;

+import java.lang.reflect.InvocationTargetException;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.FieldInterceptor;

+import org.apache.felix.ipojo.Handler;

+import org.apache.felix.ipojo.InstanceManager;

+import org.apache.felix.ipojo.parser.ParseUtils;

+import org.osgi.framework.BundleContext;

+

+/**

+ * Property class managing a property.

+ * This class allows storing property value and calling setter method too.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class Property implements FieldInterceptor {

+

+    /**

+     * Name of the property (filed name if not set).

+     */

+    private String m_name;

+

+    /**

+     * Field of the property.

+     */

+    private String m_field;

+

+    /**

+     * Setter method of the property.

+     */

+    private Callback m_method;

+

+    /**

+     * Value of the property.

+     */

+    private Object m_value;

+

+    /**

+     * Type of the property.

+     */

+    private Class m_type;

+

+    /**

+     * Handler object on to use the logger.

+     */

+    private Handler m_handler;

+    

+    /**

+     * Instance Manager.

+     */

+    private InstanceManager m_manager;

+

+    /**

+     * Configurable Property Constructor. At least the method or the field need

+     * to be referenced.

+     * 

+     * @param name : name of the property (optional)

+     * @param field : name of the field

+     * @param method : method name

+     * @param value : initial value of the property (optional)

+     * @param type : the type of the property

+     * @param manager : instance manager

+     * @param handler : handler object which manage this property.

+     * @throws ConfigurationException : occurs when the property value cannot be set.

+     */

+    public Property(String name, String field, String method, String value, String type, InstanceManager manager, Handler handler) throws ConfigurationException {

+        m_handler = handler;

+        m_manager = manager;

+        m_field = field;

+

+        if (name == null) {

+            if (m_field == null) {

+                m_name = method;

+            } else {

+                m_name = field;

+            }

+        } else {

+            m_name = name;

+        }

+        

+        m_field = field;

+        m_type = computeType(type, manager.getGlobalContext());

+        if (value != null) {

+            m_value = create(m_type, value);

+        }

+

+        if (method != null) {

+            m_method = new Callback(method, new String[] { m_type.getName() }, false, manager);

+        }

+

+    }

+

+    /**

+     * The set type method computes and returns the property type according to the given type name.

+     * @param type : the type name

+     * @param context : bundle context (used to load classes)

+     * @return the class of the given type

+     * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.

+     */

+    public static Class computeType(String type, BundleContext context) throws ConfigurationException {

+        // Array :

+        if (type.endsWith("[]")) {

+            return computeArrayType(type, context);

+        } else {

+            // Syntactic sugar to avoid writing java.lang.String

+            if ("string".equals(type) || "String".equals(type)) {

+                return java.lang.String.class;

+            } else if ("boolean".equals(type)) {

+                return Boolean.TYPE;

+            } else if ("byte".equals(type)) {

+                return Byte.TYPE;

+            } else if ("short".equals(type)) {

+                return  Short.TYPE;

+            } else if ("int".equals(type)) {

+                return Integer.TYPE;

+            } else if ("long".equals(type)) {

+                return Long.TYPE;

+            } else if ("float".equals(type)) {

+                return Float.TYPE;

+            } else if ("double".equals(type)) {

+                return Double.TYPE;

+            } else if ("char".equals(type)) {

+                return Character.TYPE;

+            } else {

+                // Non array, complex type.

+                try {

+                    return context.getBundle().loadClass(type);

+                } catch (ClassNotFoundException e) {

+                    throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());

+                } catch (SecurityException e) {

+                    throw new ConfigurationException("Security excption in setValue on " + type + " : " + e.getMessage());

+                } catch (IllegalArgumentException e) {

+                    throw new ConfigurationException("Argument problem to call the constructor of the type " + type);

+                }

+            }

+        }

+    }

+

+    /**

+     * Get the Class object of a type array.

+     * @param type : the string descriptor of the type (must end by [] )

+     * @param context : bundle context (used to load classes)

+     * @return the Class object of the given type array.

+     * @throws ConfigurationException : if the class cannot be loaded

+     */

+    private static Class computeArrayType(String type, BundleContext context) throws ConfigurationException {

+        String internalType = type.substring(0, type.length() - 2);

+        if ("string".equals(internalType) || "String".equals(internalType)) {

+            return new String[0].getClass();

+        }

+        if ("boolean".equals(internalType)) {

+            return new boolean[0].getClass();

+        }

+        if ("byte".equals(internalType)) {

+            return new byte[0].getClass();

+        }

+        if ("short".equals(internalType)) {

+            return new short[0].getClass();

+        }

+        if ("int".equals(internalType)) {

+            return new int[0].getClass();

+        }

+        if ("long".equals(internalType)) {

+            return new long[0].getClass();

+        }

+        if ("float".equals(internalType)) {

+            return new float[0].getClass();

+        }

+        if ("double".equals(internalType)) {

+            return new double[0].getClass();

+        }

+        if ("char".equals(internalType)) {

+            return new char[0].getClass();

+        }

+

+        // Complex array type.

+        try {

+            Class clazz = context.getBundle().loadClass(internalType);

+            Object[] object = (Object[]) Array.newInstance(clazz, 0);

+            return object.getClass();

+        } catch (ClassNotFoundException e) {

+            throw new ConfigurationException("Class not found exception in setValue on " + internalType);

+        } catch (SecurityException e) {

+            throw new ConfigurationException("Secutiry Exception in setValue on " + internalType);

+        } catch (IllegalArgumentException e) {

+            throw new ConfigurationException("Argument problem to call the constructor of the type " + internalType);

+        }

+    }

+

+    public String getName() {

+        return m_name;

+    }

+

+    public String getField() {

+        return m_field;

+    }

+

+    /**

+     * Get method name, null if no method.

+     * @return the method name.

+     */

+    public String getMethod() {

+        if (m_method == null) { return null; }

+        return m_method.getMethod();

+    }

+

+    /**

+     * Check if the property has a method callback.

+     * @return true if the property has a method.

+     */

+    public boolean hasMethod() {

+        return m_method != null;

+    }

+

+    /**

+     * Check if the property has a field.

+     * @return true if the property has a field.

+     */

+    public boolean hasField() {

+        return m_field != null;

+    }

+

+    public Object getValue() {

+        return m_value;

+    }

+

+    /**

+     * Fix the value of the property.

+     * @param value : the new value.

+     */

+    public void setValue(Object value) {

+        // Is the object is directly assignable to the property, affect it.

+        if (isAssignable(m_type, value)) {

+            m_value = value;

+        } else {

+            // If the object is a String, we must recreate the object from the String form

+            if (value instanceof String) {

+                try {

+                    m_value = create(m_type, (String) value);

+                } catch (ConfigurationException e) {

+                    throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());

+                }

+            } else {

+                // Error, the given property cannot be injected.

+                throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, " + value.getClass() + " received");

+            }

+        }

+    }

+

+    /**

+     * Test if the given value is assignable to the given type.

+     * @param type : class of the type

+     * @param value : object to check

+     * @return true if the object is assignable in the property of type 'type'.

+     */

+    public static boolean isAssignable(Class type, Object value) {

+        if (value == null || type.isInstance(value)) { // When the value is null, the assign works necessary.

+            return true;

+        } else if (type.isPrimitive()) {

+            // Manage all boxing types.

+            if (value instanceof Boolean && Boolean.TYPE.equals(type)) { return true; }

+            if (value instanceof Byte && Byte.TYPE.equals(type)) { return true; }

+            if (value instanceof Short && Short.TYPE.equals(type)) { return true; }

+            if (value instanceof Integer && Integer.TYPE.equals(type)) { return true; }

+            if (value instanceof Long && Long.TYPE.equals(type)) { return true; }

+            if (value instanceof Float && Float.TYPE.equals(type)) { return true; }

+            if (value instanceof Double && Double.TYPE.equals(type)) { return true; }

+            if (value instanceof Character && Character.TYPE.equals(type)) { return true; }

+            return false;

+        } else {

+            // Else return false.

+            return false;

+        }

+    }

+

+    /**

+     * Create an object of the given type with the given String value.

+     * @param type : type of the returned object

+     * @param strValue : String value.

+     * @return the object of type 'type' created from the String 'value'

+     * @throws ConfigurationException occurs when the object cannot be created.

+     */

+    public static Object create(Class type, String strValue) throws ConfigurationException {

+        if (Boolean.TYPE.equals(type)) { return new Boolean(strValue); }

+        if (Byte.TYPE.equals(type)) { return new Byte(strValue); }

+        if (Short.TYPE.equals(type)) { return new Short(strValue); }

+        if (Integer.TYPE.equals(type)) { return new Integer(strValue); }

+        if (Long.TYPE.equals(type)) { return new Long(strValue); }

+        if (Float.TYPE.equals(type)) { return new Float(strValue); }

+        if (Double.TYPE.equals(type)) { return new Double(strValue); }

+        if (Character.TYPE.equals(type)) { return new Character(strValue.charAt(0)); }

+

+        // Array :

+        if (type.isArray()) { return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue)); }

+        // Else it is a neither a primitive type neither a String -> create

+        // the object by calling a constructor with a string in argument.

+        try {

+            Constructor cst = type.getConstructor(new Class[] { String.class });

+            return cst.newInstance(new Object[] { strValue });

+        } catch (SecurityException e) {

+            throw new ConfigurationException("Security exception in create on " + type + " : " + e.getMessage());

+        } catch (NoSuchMethodException e) {

+            throw new ConfigurationException("Constructor not found exception in create on " + type + " : " + e.getMessage());

+        } catch (IllegalArgumentException e) {

+            throw new ConfigurationException("Argument problem to call the constructor of the type " + type);

+        } catch (InstantiationException e) {

+            throw new ConfigurationException("Instantiation problem  " + type);

+        } catch (IllegalAccessException e) {

+            throw new ConfigurationException("Illegal Access " + type);

+        } catch (InvocationTargetException e) {

+            throw new ConfigurationException("Invocation problem " + type + " : " + e.getTargetException().getMessage());

+        }

+

+    }

+

+    /**

+     * Create an array object containing the type 'interntype' from the String array 'values'.

+     * @param interntype : internal type of the array.

+     * @param values : String array

+     * @return the array containing objects created from the 'values' array

+     * @throws ConfigurationException occurs when the array cannot be created correctly

+     */

+    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {

+        if (Boolean.TYPE.equals(interntype)) {

+            boolean[] bool = new boolean[values.length];

+            for (int i = 0; i < values.length; i++) {

+                bool[i] = new Boolean(values[i]).booleanValue();

+            }

+            return bool;

+        }

+        if (Byte.TYPE.equals(interntype)) {

+            byte[] byt = new byte[values.length];

+            for (int i = 0; i < values.length; i++) {

+                byt[i] = new Byte(values[i]).byteValue();

+            }

+            return byt;

+        }

+        if (Short.TYPE.equals(interntype)) {

+            short[] shor = new short[values.length];

+            for (int i = 0; i < values.length; i++) {

+                shor[i] = new Short(values[i]).shortValue();

+            }

+            return shor;

+        }

+        if (Integer.TYPE.equals(interntype)) {

+            int[] ints = new int[values.length];

+            for (int i = 0; i < values.length; i++) {

+                ints[i] = new Integer(values[i]).intValue();

+            }

+            return ints;

+        }

+        if (Long.TYPE.equals(interntype)) {

+            long[] longs = new long[values.length];

+            for (int i = 0; i < values.length; i++) {

+                longs[i] = new Long(values[i]).longValue();

+            }

+            return longs;

+        }

+        if (Float.TYPE.equals(interntype)) {

+            float[] floats = new float[values.length];

+            for (int i = 0; i < values.length; i++) {

+                floats[i] = new Float(values[i]).floatValue();

+            }

+            return floats;

+        }

+        if (Double.TYPE.equals(interntype)) {

+            double[] doubles = new double[values.length];

+            for (int i = 0; i < values.length; i++) {

+                doubles[i] = new Double(values[i]).doubleValue();

+            }

+            return doubles;

+        }

+        if (Character.TYPE.equals(interntype)) {

+            char[] chars = new char[values.length];

+            for (int i = 0; i < values.length; i++) {

+                chars[i] = values[i].toCharArray()[0];

+            }

+            return chars;

+        }

+

+        // Else it is a neither a primitive type -> create the

+        // object by calling a constructor with a string in argument.

+        try {

+            Constructor cst = interntype.getConstructor(new Class[] { String.class });

+            Object[] object = (Object[]) Array.newInstance(interntype, values.length);

+            for (int i = 0; i < values.length; i++) {

+                object[i] = cst.newInstance(new Object[] { values[i].trim() });

+            }

+            return object;

+        } catch (NoSuchMethodException e) {

+            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());

+        } catch (IllegalArgumentException e) {

+            throw new ConfigurationException("Argument problem to call the constructor of the type " + interntype.getName());

+        } catch (InstantiationException e) {

+            throw new ConfigurationException("Instantiation problem  " + interntype.getName());

+        } catch (IllegalAccessException e) {

+            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());

+        } catch (InvocationTargetException e) {

+            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());

+        }

+    }

+

+    /**

+     * Invoke the setter method on the given pjo object. If no specified pojo object, will call on each created pojo object.

+     * @param instance : the created object (could be null

+     * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)

+     */

+    public void invoke(Object instance) {

+        try {

+            if (instance == null) {

+                m_method.call(new Object[] { m_value });

+            } else {

+                m_method.call(instance, new Object[] { m_value });

+            }

+        } catch (NoSuchMethodException e) {

+            m_handler.error("The method " + m_method + " does not exist in the class " + m_manager.getClassName());

+            m_manager.stop();

+        } catch (IllegalAccessException e) {

+            m_handler.error("The method " + m_method + " is not accessible in the class " + m_manager.getClassName());

+            m_manager.stop();

+        } catch (InvocationTargetException e) {

+            m_handler.error("The method " + m_method + " in the class " + m_manager.getClassName() + "throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());

+            m_manager.setState(ComponentInstance.INVALID);

+        }

+    }

+

+    /**

+     * A field value is required by the object 'pojo'.

+     * @param pojo : POJO object

+     * @param fieldName : field

+     * @param value : last value

+     * @return the value if the handler want to inject this value.

+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)

+     */

+    public Object onGet(Object pojo, String fieldName, Object value) {

+        return getValue();

+    }

+

+    /**

+     * The field 'field' receives a new value.

+     * @param pojo : pojo

+     * @param fieldName : field name

+     * @param value : new value

+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)

+     */

+    public void onSet(Object pojo, String fieldName, Object value) {

+        setValue(value);

+        

+    }

+}

diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
index 1c8ae1d..7dd3349 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
@@ -42,7 +42,7 @@
     /**

      * Bundle context against which this Tracker object is tracking.

      */

-    protected final BundleContext m_context;

+    protected BundleContext m_context;

 

     /**

      * Filter specifying search criteria for the services to track.

@@ -52,22 +52,22 @@
     /**

      * TrackerCustomizer object for this tracker.

      */

-    final TrackerCustomizer m_customizer;

+    protected TrackerCustomizer m_customizer;

 

     /**

      * Filter string for use when adding the ServiceListener. If this field is set, then certain optimizations can be taken since we don't have a user supplied filter.

      */

-    final String m_listenerFilter;

+    protected String m_listenerFilter;

 

     /**

      * Class name to be tracked. If this field is set, then we are tracking by class name.

      */

-    private final String m_trackClass;

+    private String m_trackClass;

 

     /**

      * Reference to be tracked. If this field is set, then we are tracking a single ServiceReference.

      */

-    private final ServiceReference m_trackReference;

+    private ServiceReference m_trackReference;

 

     /**

      * Tracked services: ServiceReference object -> customized. Object and ServiceListener object

@@ -126,13 +126,13 @@
         } else {

             m_customizer = customizer;

         }

-        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

+        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")";

         try {

             this.m_filter = context.createFilter(m_listenerFilter);

         } catch (InvalidSyntaxException e) { // we could only get this exception

             // if the clazz argument was

             // malformed

-            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());

         }

     }

 

@@ -157,7 +157,7 @@
             m_customizer = customizer;

         }

         if ((context == null) || (filter == null)) { // we throw a NPE here to be consistent with the other constructors

-            throw new NullPointerException();

+            throw new NullPointerException(); // NOPMD by clement on 29/02/08 14:12

         }

     }

 

@@ -188,7 +188,7 @@
                 // the initial

                 // references

             } catch (InvalidSyntaxException e) {

-                throw new RuntimeException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

+                throw new IllegalStateException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$

             }

         }

         /* Call tracked outside of synchronized region */

@@ -220,8 +220,8 @@
 

         try {

             m_context.removeServiceListener(outgoing);

-        } catch (IllegalStateException e) {

-            System.err.println("Context stopped");

+        } catch (IllegalStateException e) { //NOPMD

+            //System.err.println("Context stopped");

             /* In case the context was stopped. */

         }

         if (references != null) {

@@ -254,7 +254,7 @@
      * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

      */

     public void addedService(ServiceReference reference) {

-

+        // Nothing to do.

     }

 

     /**

@@ -266,6 +266,7 @@
      * @see TrackerCustomizer

      */

     public void modifiedService(ServiceReference reference, Object service) {

+        // Nothing to do.

     }

 

     /**

@@ -326,8 +327,7 @@
             Iterator keys = tracked.keySet().iterator();

             for (int i = 0; i < length; i++) {

                 references[i] = (ServiceReference) keys.next();

-            }

-            // The resulting array is sorted by ranking.

+            }            

             return references;

         }

     }

@@ -353,6 +353,31 @@
             return references;

         }

     }

+    

+    /**

+     * Return the list of references used by the tracker.

+     * A reference becomes used when the dependency has already

+     * call getService on this reference.

+     * @return : the list of used references.

+     */

+    public List/*<ServiceReference>*/getUsedServiceReferences() {

+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized

+        if (tracked == null || tracked.size() == 0) { // if Tracker is not open or empty

+            return null;

+        }

+        synchronized (tracked) {

+            int length = tracked.size();

+            List references = new ArrayList();

+            Iterator keys = tracked.keySet().iterator();

+            for (int i = 0; i < length; i++) {

+                Object key = keys.next(); 

+                if (tracked.get(key) != null) {

+                    references.add(key);

+                }

+            }

+            return references;

+        }

+    }

 

     /**

      * Returns a ServiceReference object for one of the services being tracked by this Tracker object.

@@ -388,11 +413,13 @@
         Object object = null;

         synchronized (tracked) {

             object = tracked.get(reference);

-            if (object != null) { // The object was already get.

-                return object;

-            } else if (tracked.containsKey(reference)) { // Not already get

-                object = m_context.getService(reference);

-                tracked.put(reference, object);

+            if (object == null) {

+                if (tracked.containsKey(reference)) { // Not already get but already tracked.

+                    object = m_context.getService(reference);

+                    tracked.put(reference, object);

+                    return object;

+                }

+            } else { // The object was already get.

                 return object;

             }

             // Not already tracked.

@@ -430,10 +457,10 @@
         synchronized (tracked) {

             ServiceReference[] references = getServiceReferences();

             int length = 0;

-            if (references != null) {

-                length = references.length;

-            } else {

+            if (references == null) {

                 return null;

+            } else {

+                length = references.length;

             }

             Object[] objects = new Object[length];

             for (int i = 0; i < length; i++) {

@@ -541,7 +568,7 @@
             while (true) {

                 ServiceReference reference;

                 synchronized (this) {

-                    if (m_initial.size() == 0) { //  if there are no more inital services

+                    if (m_initial.isEmpty()) { //  if there are no more inital services

                         return; // we are done

                     }

 

@@ -580,14 +607,14 @@
             switch (event.getType()) {

                 case ServiceEvent.REGISTERED:

                 case ServiceEvent.MODIFIED:

-                    if (m_listenerFilter != null) { // constructor supplied filter

-                        track(reference);

-                    } else { // user supplied filter

+                    if (m_listenerFilter == null) { // user supplied filter 

                         if (m_filter.match(reference)) {

                             track(reference); // Arrival

                         } else {

                             untrack(reference); // Departure

                         }

+                    } else { // constructor supplied filter

+                        track(reference);

                     }

                     break;

                 case ServiceEvent.UNREGISTERING:

diff --git a/ipojo/core/src/main/resources/metadata.xml b/ipojo/core/src/main/resources/metadata.xml
index 9d02336..3163416 100644
--- a/ipojo/core/src/main/resources/metadata.xml
+++ b/ipojo/core/src/main/resources/metadata.xml
@@ -1,41 +1,27 @@
 <ipojo>

-<!-- Primitives handler -->

-<handler classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler" name="controller" architecture="false"/>

-<handler classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler" name="callback" level="1" architecture="false"/>

-<handler classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler" name="requires" level="0" architecture="false">

-	<controller field="m_state"/>

-</handler>

-<handler classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler" name="provides" level="3" architecture="false"/>

-<handler classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler" name="properties" level="1" architecture="false"/>

-<handler classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler" name="architecture" architecture="false">

-	<provides>

-		<property field="m_name" name="instance.name" value=""/>

-	</provides>

-</handler>

-

-<!-- Composite Handler -->

-<handler classname="org.apache.felix.ipojo.composite.instance.InstanceHandler" name="instance" type="composite" architecture="false">

-	<controller field="m_isValid"/>

-	<requires filter="(&amp;(factory.state=1)(factory.name=*))" field="m_factories" optional="true" architecture="false">

-		<callback type="bind" method="bindFactory"/>

-		<callback type="unbind" method="unbindFactory"/>

-	</requires>

-</handler>

-<handler classname="org.apache.felix.ipojo.composite.service.importer.ImportHandler" name="requires" type="composite" architecture="false">

-	<controller field="m_valid"/>

-</handler>

-<handler classname="org.apache.felix.ipojo.composite.service.importer.ExportHandler" name="exports" type="composite" architecture="false">

-	<controller field="m_valid"/>

-</handler>

-<handler classname="org.apache.felix.ipojo.composite.service.instantiator.ServiceInstantiatorHandler" name="service" type="composite" architecture="false">

-	<controller field="m_isValid"/>

-</handler>

-<handler classname="org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler" name="provides" type="composite" architecture="false">

-	<controller field="m_valid"/>

-</handler>

-<handler classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler" name="architecture" type="composite" architecture="false">

-	<provides>

-		<property field="m_name" name="instance.name" value=""/>

-	</provides>

-</handler>

+	<!-- Primitives handler -->

+	<handler

+		classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler"

+		name="controller" architecture="false" />

+	<handler

+		classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler"

+		name="callback" level="1" architecture="false" />

+	<handler

+		classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler"

+		name="requires" level="0" architecture="false">

+		<!-- <controller field="m_state"/>  -->

+	</handler>

+	<handler

+		classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler"

+		name="provides" level="3" architecture="false" />

+	<handler

+		classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler"

+		name="properties" level="1" architecture="false" />

+	<handler

+		classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler"

+		name="architecture" architecture="false">

+		<provides>

+			<property field="m_name" name="instance.name" value="" />

+		</provides>

+	</handler>

 </ipojo>
\ No newline at end of file
diff --git a/ipojo/event.admin.handler/pom.xml b/ipojo/event.admin.handler/pom.xml
index fb69c57..840cf9f 100644
--- a/ipojo/event.admin.handler/pom.xml
+++ b/ipojo/event.admin.handler/pom.xml
@@ -1,84 +1,90 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

 <project>

-  <modelVersion>4.0.0</modelVersion>

-  <packaging>bundle</packaging>

-  <name>iPOJO Event Admin Handler</name>

-  <groupId>org.apache.felix</groupId>

-  <version>0.7.5-SNAPSHOT</version>

-  <artifactId>org.apache.felix.ipojo.handler.event</artifactId>

-	  

-  <dependencies>

-	  <dependency>

-  			<groupId>org.apache.felix</groupId>

-      		<artifactId>org.apache.felix.ipojo</artifactId>

-	        <version>0.7.5-SNAPSHOT</version>

-	  </dependency>

-	  <dependency>

-  			<groupId>org.apache.felix</groupId>

-      		<artifactId>org.apache.felix.ipojo.metadata</artifactId>

-	      	<version>0.7.5-SNAPSHOT</version>

-	  </dependency>

-	  <dependency>

-  			<groupId>org.apache.felix</groupId>

-      		<artifactId>org.osgi.core</artifactId>

-      		<version>1.1.0-SNAPSHOT</version>

-	  </dependency>

-	  <dependency>

-	     <groupId>org.apache.felix</groupId>

-  		 <artifactId>org.osgi.compendium</artifactId>

-         <version>1.0.0</version>
-	</dependency>

-  </dependencies>

-  

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Event Admin Handler</name>

+	<artifactId>org.apache.felix.ipojo.handler.event</artifactId>

 

-  

-  <build>

-    <plugins>

-      <plugin>

-        <groupId>org.apache.felix</groupId>

-        <artifactId>maven-bundle-plugin</artifactId>

-        <version>1.4.0</version>
-        <extensions>true</extensions>

-        <configuration>

-          <instructions>

-            <Private-Package>org.apache.felix.ipojo.handler.event</Private-Package>

-            <Bundle-Name>${pom.name}</Bundle-Name>

-            <Bundle-SymbolicName>ipojo.event.admin.handler</Bundle-SymbolicName>

-          </instructions>

-        </configuration>

-      </plugin>

-      <plugin>

-	      <groupId>org.apache.felix</groupId>

-	      <artifactId>maven-ipojo-plugin</artifactId>

-          <version>${pom.version}</version>

-		  <executions>

-          	<execution>

-            	<goals>

-	              <goal>ipojo-bundle</goal>

-               </goals>

-            <configuration>

-   				<metadata>metadata.xml</metadata>

-            </configuration>

-          </execution>

-        </executions>

-      </plugin>

-    </plugins>

-  </build>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.compendium</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Private-Package>

+							org.apache.felix.ipojo.handler.event

+						</Private-Package>

+						<Bundle-Name>${pom.name}</Bundle-Name>

+						<Bundle-SymbolicName>

+							ipojo.event.admin.handler

+						</Bundle-SymbolicName>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<metadata>metadata.xml</metadata>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

 </project>

diff --git a/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberHandler.java b/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberHandler.java
index b2654ca..5c090c3 100644
--- a/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberHandler.java
+++ b/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberHandler.java
@@ -27,13 +27,13 @@
 import org.apache.felix.ipojo.ConfigurationException;

 import org.apache.felix.ipojo.InstanceManager;

 import org.apache.felix.ipojo.PrimitiveHandler;

-import org.apache.felix.ipojo.architecture.ComponentDescription;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

 import org.apache.felix.ipojo.architecture.PropertyDescription;

 import org.apache.felix.ipojo.metadata.Element;

-import org.apache.felix.ipojo.parser.ManipulationMetadata;

 import org.apache.felix.ipojo.parser.MethodMetadata;

+import org.apache.felix.ipojo.parser.ParseUtils;

+import org.apache.felix.ipojo.parser.PojoMetadata;

 import org.apache.felix.ipojo.util.Callback;

-import org.apache.felix.ipojo.util.Logger;

 import org.osgi.framework.InvalidSyntaxException;

 import org.osgi.service.event.Event;

 import org.osgi.service.event.EventHandler;

@@ -71,7 +71,7 @@
      * @throws ConfigurationException : metadata are incorrect.

      * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentDescription, org.apache.felix.ipojo.metadata.Element)

      */

-    public void initializeComponentFactory(ComponentDescription cd, Element metadata) throws ConfigurationException {

+    public void initializeComponentFactory(ComponentTypeDescription cd, Element metadata) throws ConfigurationException {

         // Update the current component description

         Dictionary dict = new Properties();

         cd.addProperty(new PropertyDescription("event.topics", Dictionary.class.getName(), dict.toString()));

@@ -93,11 +93,11 @@
 

         // Store the component manager

         m_manager = getInstanceManager();

-        ManipulationMetadata mm = new ManipulationMetadata(metadata);

+        PojoMetadata mm = getFactory().getPojoMetadata();

 

         // Get Metadata subscribers

         Element[] subscribers = metadata.getElements("subscriber", NAMESPACE);

-        if (subscribers.length > 0) {

+        if (subscribers != null) {

             // then check publishers are well formed and fill the publishers'

             // map

             for (int i = 0; i < subscribers.length; i++) {

@@ -109,25 +109,24 @@
                         Callback cb = new Callback(methodMetadata, m_manager);

                         eventAdminSubscriberMetadata.setCallback(cb);

                     } else {

-                        log(Logger.WARNING, " EVENT HANDLER SUBSCRIBERS : malformed subscriber : the method " + eventAdminSubscriberMetadata.getCallbackStr() + "(Event myEvent) is not present in the component");

+                        warn(" EVENT HANDLER SUBSCRIBERS : malformed subscriber : the method " + eventAdminSubscriberMetadata.getCallbackStr() + "(Event myEvent) is not present in the component");

                         throw new ConfigurationException("EVENT HANDLER SUBSCRIBERS : malformed subscriber : the method " + eventAdminSubscriberMetadata.getCallbackStr() + "(Event myEvent) is not present in the component");

                     }

                     m_subEvent.add(eventAdminSubscriberMetadata);

                 } else {

-                    log(Logger.WARNING, " EVENT HANDLER SUBSCRIBERS : malformed subscriber !");

+                    warn(" EVENT HANDLER SUBSCRIBERS : malformed subscriber !");

                     throw new ConfigurationException("EVENT HANDLER SUBSCRIBERS : malformed subscriber !");

                 }

             }

-            log(Logger.INFO, " EVENT HANDLER SUBSCRIBERS : Suscribers detected !");

         } else {

-            log(Logger.ERROR, " EVENT HANDLER SUBSCRIBERS : no Suscribers detected !");

+            error(" EVENT HANDLER SUBSCRIBERS : no Suscribers detected !");

             throw new ConfigurationException(" EVENT HANDLER SUBSCRIBERS : no Suscribers detected !");

         }

 

         // if well formed publishers or subscribers found

         if (!m_subEvent.isEmpty()) {

             // register the handler

-            log(Logger.INFO, " EVENT HANDLER SUBSCRIBERS has been configured !");

+            info(" EVENT HANDLER SUBSCRIBERS has been configured !");

         } else {

             return;

         }

@@ -178,8 +177,6 @@
      * @see org.apache.felix.ipojo.Handler#start()

      */

     public void start() {

-        log(Logger.INFO, " EVENT HANDLER SUBSCRIBERS STARTING!!!");

-

         if (!m_subEvent.isEmpty()) {

             // build the topic to listen

             // Topics is a merge of all required topics by subscribers

@@ -198,9 +195,7 @@
             }

 

             // Put the m_topics properties to the good value

-            m_topics = topics.split(",");

-

-            log(Logger.INFO, " EVENT HANDLER SUBSCRIBERS : EventHandler registered object: " + this);

+            m_topics = ParseUtils.split(topics, ",");

         }

     }

 

@@ -249,7 +244,7 @@
                             c.call(new Object[] { event });

                         }

                     } catch (Exception e) {

-                        log(Logger.ERROR, "EVENT HANDLER SUBSCRIBERS CALLBACK error : " + eventSubscriberData.getCallbackStr() + " exception :" + e + " Cause : " + e.getCause());

+                        error("EVENT HANDLER SUBSCRIBERS CALLBACK error : " + eventSubscriberData.getCallbackStr() + " exception :" + e.getMessage());

                         // stop the component :

                         m_manager.setState(InstanceManager.INVALID);

                     }

diff --git a/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberMetadata.java b/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberMetadata.java
index 989f633..826f547 100644
--- a/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberMetadata.java
+++ b/ipojo/event.admin.handler/src/main/java/org/apache/felix/ipojo/handler/event/EventAdminSubscriberMetadata.java
@@ -20,6 +20,7 @@
 

 import org.apache.felix.ipojo.InstanceManager;

 import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.ParseUtils;

 import org.apache.felix.ipojo.util.Callback;

 import org.apache.felix.ipojo.util.Logger;

 import org.osgi.framework.Filter;

@@ -43,7 +44,7 @@
     private Callback m_callback;

 

     /**

-     * Listenned topics.

+     * Listened topics.

      */

     private String m_topics;

 

@@ -112,12 +113,11 @@
      * @return true if the given topic is a listenned topic.

      */

     public boolean matchingTopic(String topic) {

-        return EventUtil.matches(topic, m_topics.split(","));

+        return EventUtil.matches(topic, ParseUtils.split(m_topics, ","));

     }

 

     /**

-     * Is the subscriber metadata valid ?

-     * This method check only the existence of a callback and a name attribute.

+     * Is the subscriber metadata valid ? This method check only the existence of a callback and a name attribute.

      * @param subscriber : metadata.

      * @return true if the metadata is valid.

      */

@@ -174,8 +174,7 @@
     }

 

     /**

-     * Create and set the filter.

-     * The filter is create from the given argument.

+     * Create and set the filter. The filter is create from the given argument.

      * @param filter : the String form of the LDAP filter.

      * @throws InvalidSyntaxException : occurs when the given filter is invalid.

      */

diff --git a/ipojo/examples/junit4osgi/felix-command/metadata.xml b/ipojo/examples/junit4osgi/felix-command/metadata.xml
new file mode 100644
index 0000000..87f7db1
--- /dev/null
+++ b/ipojo/examples/junit4osgi/felix-command/metadata.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component

+		className="org.apache.felix.ipojo.junit4osgi.command.JunitCommand"

+		factory="false">

+		<requires field="runner" />

+		<provides />

+	</component>

+	<instance

+		component="org.apache.felix.ipojo.junit4osgi.command.JunitCommand" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/junit4osgi/felix-command/pom.xml b/ipojo/examples/junit4osgi/felix-command/pom.xml
new file mode 100644
index 0000000..f810d59
--- /dev/null
+++ b/ipojo/examples/junit4osgi/felix-command/pom.xml
@@ -0,0 +1,95 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>Junit4Osgi</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Junit4Osgi-Felix-Command</name>

+	<artifactId>

+		org.apache.felix.ipojo.junit4osgi.felix-command

+	</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>${pom.groupId}</groupId>

+			<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.shell</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>

+							iPOJO OSGi Junit Runner - Felix Command

+						</Bundle-Name>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.junit4osgi.command

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/junit4osgi/felix-command/src/main/java/org/apache/felix/ipojo/junit4osgi/command/JunitCommand.java b/ipojo/examples/junit4osgi/felix-command/src/main/java/org/apache/felix/ipojo/junit4osgi/command/JunitCommand.java
new file mode 100644
index 0000000..a217a9e
--- /dev/null
+++ b/ipojo/examples/junit4osgi/felix-command/src/main/java/org/apache/felix/ipojo/junit4osgi/command/JunitCommand.java
@@ -0,0 +1,111 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.command;

+

+import java.io.PrintStream;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.ListIterator;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestFailure;

+import junit.framework.TestResult;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiJunitRunner;

+import org.apache.felix.shell.Command;

+

+/**

+ * Felix shell command. Allow to run tests.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class JunitCommand implements Command {

+

+    private OSGiJunitRunner runner;

+

+    private List<String> getNamesFromTests(List<Test> list) {

+        List<String> names = new ArrayList<String>(list.size());

+        for (int i = 0; i < list.size(); i++) {

+            if (list.get(i) instanceof TestCase) {

+                names.add(((TestCase) list.get(i)).getName());

+            }

+            if (list.get(i) instanceof TestSuite) {

+                String name = ((TestSuite) list.get(i)).getName();

+                if (name == null) {

+                    name = ((TestSuite) list.get(i)).toString();

+                }

+                names.add(name);

+            }

+        }

+        return names;

+    }

+

+    public void execute(String line, PrintStream out, PrintStream err) {

+        line = line.substring(getName().length()).trim();

+        List<TestResult> tr = null;

+        if (line.equals("all")) {

+            if (runner.getTests() == null) {

+                err.println("No tests to execute");

+                return;

+            } else {

+                out.println("Executing " + getNamesFromTests(runner.getTests()));

+                tr = runner.run();

+            }

+        } else {

+            try {

+                Long bundleId = new Long(line);

+                if (runner.getTests(bundleId) == null) {

+                    err.println("No tests to execute");

+                    return;

+                } else {

+                    out.println("Executing " + getNamesFromTests(runner.getTests(bundleId)));

+                    tr = runner.run(bundleId);

+                }

+            } catch (NumberFormatException e) {

+                err.println("Unable to parse id " + line);

+                return;

+            }

+        }

+

+        ListIterator<TestResult> it = tr.listIterator();

+        while (it.hasNext()) {

+            TestResult result = it.next();

+            if (result.failureCount() != 0) {

+                TestFailure fail = (TestFailure) result.failures().nextElement();

+                out.println(fail.trace());

+                return;

+            }

+        }

+

+    }

+

+    public String getName() {

+        return "junit";

+    }

+

+    public String getShortDescription() {

+        return "launch junit tests";

+    }

+

+    public String getUsage() {

+        return "junit";

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/immediate-launcher/metadata.xml b/ipojo/examples/junit4osgi/immediate-launcher/metadata.xml
new file mode 100644
index 0000000..648ab67
--- /dev/null
+++ b/ipojo/examples/junit4osgi/immediate-launcher/metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component

+		className="org.apache.felix.ipojo.junit4osgi.command.ImmediateRunner"

+		factory="false">

+		<requires field="runner" />

+		<callback method="start" transition="validate" />

+	</component>

+	<instance

+		component="org.apache.felix.ipojo.junit4osgi.command.ImmediateRunner"

+		name="immediate-runner" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/junit4osgi/immediate-launcher/pom.xml b/ipojo/examples/junit4osgi/immediate-launcher/pom.xml
new file mode 100644
index 0000000..18cfb31
--- /dev/null
+++ b/ipojo/examples/junit4osgi/immediate-launcher/pom.xml
@@ -0,0 +1,95 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>Junit4Osgi</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Junit4Osgi-Immediate-Runner</name>

+	<artifactId>

+		org.apache.felix.ipojo.junit4osgi.immediate-runner

+	</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>${pom.groupId}</groupId>

+			<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.shell</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>

+							iPOJO OSGi Junit Runner - Immediate Runner

+						</Bundle-Name>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.junit4osgi.command

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/junit4osgi/immediate-launcher/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ImmediateRunner.java b/ipojo/examples/junit4osgi/immediate-launcher/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ImmediateRunner.java
new file mode 100644
index 0000000..199cdf6
--- /dev/null
+++ b/ipojo/examples/junit4osgi/immediate-launcher/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ImmediateRunner.java
@@ -0,0 +1,35 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.command;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiJunitRunner;

+

+/**

+ * Felix shell command. Allow to run tests.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ImmediateRunner {

+

+    private OSGiJunitRunner runner;

+    

+    public void start() {

+        runner.run();

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/metadata.xml b/ipojo/examples/junit4osgi/junit4osgi/metadata.xml
new file mode 100644
index 0000000..83d84d3
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/metadata.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO xmlns:extender="org.apache.felix.ipojo.extender">

+	<Component

+		className="org.apache.felix.ipojo.junit4osgi.impl.JunitExtender">

+		<extender:extender extension="Test-Suite"

+			onArrival="onBundleArrival" onDeparture="onBundleDeparture" />

+		<callback transition="invalidate" method="stopping" />

+		<callback transition="validate" method="starting" />

+		<provides />

+	</Component>

+	<instance

+		component="org.apache.felix.ipojo.junit4osgi.impl.JunitExtender" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/junit4osgi/junit4osgi/pom.xml b/ipojo/examples/junit4osgi/junit4osgi/pom.xml
new file mode 100644
index 0000000..e4ffbf4
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/pom.xml
@@ -0,0 +1,103 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>Junit4Osgi</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Junit4Osgi</name>

+	<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>

+							iPOJO OSGi Junit Runner

+						</Bundle-Name>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.junit4osgi.impl,

+							org.apache.felix.ipojo.junit4osgi.test

+						</Private-Package>

+						<Export-Package>

+							org.apache.felix.ipojo.junit4osgi, junit.*

+						</Export-Package>

+						<Test-Suite>

+							org.apache.felix.ipojo.junit4osgi.test.TestTestCase,

+							org.apache.felix.ipojo.junit4osgi.test.TestOSGiTestCase,

+							org.apache.felix.ipojo.junit4osgi.test.TestTestSuite,

+							org.apache.felix.ipojo.junit4osgi.test.TestOSGiTestSuite

+						</Test-Suite>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiJunitRunner.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiJunitRunner.java
new file mode 100644
index 0000000..57a67d6
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiJunitRunner.java
@@ -0,0 +1,72 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi;

+

+import java.io.PrintStream;

+import java.util.List;

+

+import junit.framework.Test;

+import junit.framework.TestResult;

+

+/**

+ * OSGi Junit Runner.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public interface OSGiJunitRunner {

+    

+    /**

+     * Set the output stream of the runner.

+     * @param ps : print stream.

+     */

+    void setResultPrinter(PrintStream ps);

+    

+    /**

+     * Run the tests.

+     * @return the list of TestResult.

+     */

+    List<TestResult>  run();

+    

+    /**

+     * Run the tests from the given bundle.

+     * @param bundleId : bundle containing the tests. 

+     * @return the list of the results.

+     */

+    List<TestResult> run(long bundleId);

+    

+    /**

+     * Get the list of available test suites.

+     * @return the list of test suites.

+     */

+    List<Test> getTests();

+    

+    /**

+     * Get the tests from the given bundle. 

+     * @param bundleId : bundle id.

+     * @return the list of test suites contained in the given bundle.

+     */

+    List<Test> getTests(long bundleId);

+    

+    /**

+     * Run the given test.

+     * @param test : test to execute.

+     * @return the result.

+     */

+    public TestResult run(Test test);

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java
new file mode 100644
index 0000000..e10ad04
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java
@@ -0,0 +1,187 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi;

+

+import junit.framework.TestCase;

+

+import org.osgi.framework.BundleContext;

+

+/**

+ * OSGi Test Case. Allow the injection of the bundle context.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class OSGiTestCase extends TestCase {

+

+    protected BundleContext context;

+

+    public void setBundleContext(BundleContext bc) {

+        context = bc;

+    }

+

+    /**

+     * Asserts that two doubles are equal. If they are not an AssertionFailedError is thrown with the given message.

+     */

+    static public void assertEquals(String message, double expected, double actual) {

+        if (Double.compare(expected, actual) != 0) {

+            fail(formatEqualsMessage(message, expected, actual));

+        }

+    }

+

+    static String formatEqualsMessage(String message, Object expected, Object actual) {

+        String formatted = "";

+        if (message != null) {

+            formatted = message + " ";

+        }

+        return formatted + "expected:<" + expected + "> but was:<" + actual + ">";

+    }

+

+    static String formatNotEqualsMessage(String message, Object o1, Object o2) {

+        String formatted = "";

+        if (message != null) {

+            formatted = message + " ";

+        }

+        return formatted + "o1:<" + o1 + "> is equals to o2:<" + o2 + ">";

+    }

+

+    static String formatContainsMessage(String message, Object[] array, Object txt) {

+        String formatted = "";

+        if (message != null) {

+            formatted = message + " ";

+        }

+

+        String arr = null;

+        for (int i = 0; i < array.length; i++) {

+            if (arr == null) {

+                arr = "[" + array[i];

+            } else {

+                arr += "," + array[i];

+            }

+        }

+        arr += "]";

+

+        return formatted + "array:" + arr + " does not contains:<" + txt + ">";

+    }

+

+    static public void assertNotEquals(String message, Object o1, Object o2) {

+        if (o1.equals(o2)) {

+            fail(formatNotEqualsMessage(message, o1, o2));

+        }

+    }

+

+    static public void assertContains(String message, String[] array, String txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i].equals(txt)) {

+                return;

+            }

+        }

+        fail(formatContainsMessage(message, array, txt));

+    }

+

+    static public void assertContains(String message, byte[] array, int txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Byte[] bytes = new Byte[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Byte(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, short[] array, int txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Short[] bytes = new Short[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Short(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, int[] array, int txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Integer[] bytes = new Integer[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Integer(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, long[] array, long txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Long[] bytes = new Long[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Long(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, float[] array, float txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Float[] bytes = new Float[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Float(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, double[] array, double txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Double[] bytes = new Double[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Double(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+    static public void assertContains(String message, char[] array, char txt) {

+        for (int i = 0; i < array.length; i++) {

+            if (array[i] == txt) {

+                return;

+            }

+        }

+        Character[] bytes = new Character[array.length];

+        for (int i = 0; i < array.length; i++) {

+            bytes[i] = new Character(array[i]);

+        }

+        fail(formatContainsMessage(message, bytes, txt));

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestSuite.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestSuite.java
new file mode 100644
index 0000000..8e7795a
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestSuite.java
@@ -0,0 +1,87 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi;

+

+import junit.framework.Test;

+import junit.framework.TestCase;

+import junit.framework.TestResult;

+import junit.framework.TestSuite;

+

+import org.osgi.framework.BundleContext;

+

+/**

+ * OSGi Test Suite.

+ * Allow the injection of the bundle context.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class OSGiTestSuite extends TestSuite {

+

+    protected BundleContext context;

+

+    public OSGiTestSuite(Class clazz, BundleContext bc) {

+        super(clazz);

+        context = bc;

+    }

+

+    public OSGiTestSuite(BundleContext bc) {

+        super();

+        context = bc;

+    }

+

+    public OSGiTestSuite(String name, BundleContext bc) {

+        super(name);

+        context = bc;

+    }

+

+    public OSGiTestSuite(Class clazz, String name, BundleContext bc) {

+        super(clazz, name);

+        context = bc;

+    }

+

+    public void setBundleContext(BundleContext bc) {

+        context = bc;

+    }

+

+    /**

+     * Adds the tests from the given class to the suite

+     */

+    public void addTestSuite(Class testClass) {

+        if (OSGiTestCase.class.isAssignableFrom(testClass)) {

+            addTest(new OSGiTestSuite(testClass, context));

+        } else if (TestCase.class.isAssignableFrom(testClass)) {

+            addTest(new TestSuite(testClass));

+        } else {

+            System.out.println("Error : the " + testClass + " is not a valid test class");

+        }

+    }

+

+    public void runTest(Test test, TestResult result) {

+        if (test instanceof OSGiTestSuite) {

+            ((OSGiTestSuite) test).context = context;

+            test.run(result);

+        } else if (test instanceof OSGiTestCase) {

+            ((OSGiTestCase) test).context = context;

+            test.run(result);

+        } else {

+            test.run(result);

+        }

+

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/JunitExtender.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/JunitExtender.java
new file mode 100644
index 0000000..34f0382
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/JunitExtender.java
@@ -0,0 +1,302 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.impl;

+

+import java.io.PrintStream;

+import java.lang.reflect.Field;

+import java.lang.reflect.InvocationTargetException;

+import java.lang.reflect.Method;

+import java.lang.reflect.Modifier;

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Map.Entry;

+

+import junit.framework.Test;

+import junit.framework.TestResult;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiJunitRunner;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.Bundle;

+import org.osgi.framework.BundleContext;

+

+/**

+ * Detect test suite from installed bundles.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class JunitExtender implements OSGiJunitRunner {

+

+    public static final String SUITE_METHODNAME = "suite";

+

+    private Map<Bundle, List<Class>> m_suites = new HashMap<Bundle, List<Class>>();

+

+    private ResultPrinter m_printer = new ResultPrinter(System.out);

+

+    void onBundleArrival(Bundle bundle, String header) {

+        String[] tss = header.split(",");

+        for (int i = 0; i < tss.length; i++) {

+            try {

+                if (tss[i].length() != 0) {

+                    System.out.println("Loading " + tss[i]);

+                    Class<? extends Test> clazz = bundle.loadClass(tss[i].trim());

+                    addTestSuite(bundle, clazz);

+                }

+            } catch (ClassNotFoundException e) {

+                System.err.println("The test suite " + tss[i] + " is not in the bundle " + bundle.getBundleId() + " : " + e.getMessage());

+            }

+        }

+    }

+

+    private synchronized void addTestSuite(Bundle bundle, Class<? extends Test> test) {

+        List<Class> list = m_suites.get(bundle);

+        if (list == null) {

+            list = new ArrayList<Class>();

+            list.add(test);

+            m_suites.put(bundle, list);

+        } else {

+            list.add(test);

+        }

+    }

+

+    private synchronized void removeTestSuites(Bundle bundle) {

+        m_suites.remove(bundle);

+    }

+

+    void onBundleDeparture(Bundle bundle) {

+        removeTestSuites(bundle);

+    }

+

+    public void setResultPrinter(PrintStream pw) {

+        m_printer = new ResultPrinter(pw);

+    }

+

+    public synchronized List<TestResult> run() {

+        List<TestResult> results = new ArrayList<TestResult>(m_suites.size());

+        Iterator<Entry<Bundle, List<Class>>> it = m_suites.entrySet().iterator();

+        while (it.hasNext()) {

+            Entry<Bundle, List<Class>> entry = it.next();

+            Bundle bundle = entry.getKey();

+            List<Class> list = m_suites.get(bundle);

+            for (int i = 0; i < list.size(); i++) {

+                Test test = createTestFromClass(list.get(i), bundle);

+                TestResult tr = doRun(test);

+                results.add(tr);

+            }

+        }

+        return results;

+    }

+

+    private TestResult doRun(Test test) {

+        TestResult result = new TestResult();

+        result.addListener(m_printer);

+        long startTime = System.currentTimeMillis();

+

+        test.run(result);

+

+        long endTime = System.currentTimeMillis();

+        long runTime = endTime - startTime;

+        m_printer.print(result, runTime);

+

+        return result;

+    }

+

+    private Test createTestFromClass(Class<?> clazz, Bundle bundle) {

+        Method suiteMethod = null;

+        boolean bc = false;

+        try {

+            suiteMethod = clazz.getMethod(SUITE_METHODNAME, new Class[0]);

+        } catch (Exception e) {

+            // try to use a suite method receiving a bundle context

+            try {

+                suiteMethod = clazz.getMethod(SUITE_METHODNAME, new Class[] { BundleContext.class });

+                bc = true;

+            } catch (Exception e2) {

+                // try to extract a test suite automatically

+                if (OSGiTestSuite.class.isAssignableFrom(clazz)) {

+                    OSGiTestSuite ts = new OSGiTestSuite(clazz, getBundleContext(bundle));

+                    return ts;

+                } else if (OSGiTestCase.class.isAssignableFrom(clazz)) {

+                    OSGiTestSuite ts = new OSGiTestSuite(clazz, getBundleContext(bundle));

+                    return ts;

+                } else {

+                    return new TestSuite(clazz);

+                }

+            }

+        }

+

+        if (!Modifier.isStatic(suiteMethod.getModifiers())) {

+            System.err.println("Suite() method must be static");

+            return null;

+        }

+        Test test = null;

+        try {

+            if (bc) {

+                test = (Test) suiteMethod.invoke(null, new Object[] { getBundleContext(bundle) }); // static method injection the bundle context

+            } else {

+                test = (Test) suiteMethod.invoke(null, (Object[]) new Class[0]); // static method

+            }

+        } catch (InvocationTargetException e) {

+            System.err.println("Failed to invoke suite():" + e.getTargetException().toString());

+            return null;

+        } catch (IllegalAccessException e) {

+            System.err.println("Failed to invoke suite():" + e.toString());

+            return null;

+        }

+

+        return test;

+    }

+

+    public synchronized List<Test> getTests() {

+        List<Test> results = new ArrayList<Test>();

+        Iterator<Entry<Bundle, List<Class>>> it = m_suites.entrySet().iterator();

+        while (it.hasNext()) {

+            Entry<Bundle, List<Class>> entry = it.next();

+            Bundle bundle = entry.getKey();

+            List<Class> list = m_suites.get(bundle);

+            for (int i = 0; i < list.size(); i++) {

+                Test test = createTestFromClass(list.get(i), bundle);

+                results.add(test);

+            }

+        }

+        return results;

+    }

+

+    public TestResult run(Test test) {

+        return doRun(test);

+    }

+

+    public synchronized List<Test> getTests(long bundleId) {

+        Iterator<Entry<Bundle, List<Class>>> it = m_suites.entrySet().iterator();

+        while (it.hasNext()) {

+            Entry<Bundle, List<Class>> entry = it.next();

+            Bundle bundle = entry.getKey();

+            if (bundle.getBundleId() == bundleId) {

+                List<Test> results = new ArrayList<Test>();

+                List<Class> list = m_suites.get(bundle);

+                for (int i = 0; i < list.size(); i++) {

+                    Test test = createTestFromClass(list.get(i), bundle);

+                    results.add(test);

+                }

+                return results;

+            }

+        }

+        return null;

+    }

+

+    public synchronized List<TestResult> run(long bundleId) {

+        Iterator<Entry<Bundle, List<Class>>> it = m_suites.entrySet().iterator();

+        while (it.hasNext()) {

+            Entry<Bundle, List<Class>> entry = it.next();

+            Bundle bundle = entry.getKey();

+            if (bundle.getBundleId() == bundleId) {

+                List<TestResult> results = new ArrayList<TestResult>();

+                List<Class> list = m_suites.get(bundle);

+                for (int i = 0; i < list.size(); i++) {

+                    Test test = createTestFromClass(list.get(i), bundle);

+                    TestResult tr = doRun(test);

+                    results.add(tr);

+                }

+                return results;

+            }

+        }

+        return null;

+    }

+

+    public synchronized void stopping() {

+        System.out.println("Cleaning test suites ...");

+        m_suites.clear();

+    }

+    

+    public void starting() {

+        System.out.println("Junit Extender starting ...");

+    }

+

+    private BundleContext getBundleContext(Bundle bundle) {

+        if (bundle == null) { return null; }

+

+        // getBundleContext (OSGi 4.1)

+        Method meth = null;

+        try {

+            meth = bundle.getClass().getMethod("getBundleContext", new Class[0]);

+        } catch (SecurityException e) {

+            // Nothing do to, will try the Equinox method

+        } catch (NoSuchMethodException e) {

+            // Nothing do to, will try the Equinox method

+        }

+

+        // try Equinox getContext if not found.

+        if (meth == null) {

+            try {

+                meth = bundle.getClass().getMethod("getContext", new Class[0]);

+            } catch (SecurityException e) {

+                // Nothing do to, will try field inspection

+            } catch (NoSuchMethodException e) {

+                // Nothing do to, will try field inspection

+            }

+        }

+

+        if (meth != null) {

+            if (! meth.isAccessible()) {

+                meth.setAccessible(true);

+            }

+            try {

+                return (BundleContext) meth.invoke(bundle, new Object[0]);

+            } catch (IllegalArgumentException e) {

+                err("Cannot get the BundleContext by invoking " + meth.getName(), e);

+                return null;

+            } catch (IllegalAccessException e) {

+                err("Cannot get the BundleContext by invoking " + meth.getName(), e);

+                return null;

+            } catch (InvocationTargetException e) {

+                err("Cannot get the BundleContext by invoking " + meth.getName(), e);

+                return null;

+            }

+        }

+

+        // Else : Field inspection (KF and Prosyst)        

+        Field[] fields = bundle.getClass().getDeclaredFields();

+        for (int i = 0; i < fields.length; i++) {

+            if (BundleContext.class.isAssignableFrom(fields[i].getType())) {

+                if (! fields[i].isAccessible()) {

+                    fields[i].setAccessible(true);

+                }

+                try {

+                    return (BundleContext) fields[i].get(bundle);

+                } catch (IllegalArgumentException e) {

+                    err("Cannot get the BundleContext by invoking " + meth.getName(), e);

+                    return null;

+                } catch (IllegalAccessException e) {

+                    err("Cannot get the BundleContext by invoking " + meth.getName(), e);

+                    return null;

+                }

+            }

+        }

+        err("Cannot find the BundleContext for " + bundle.getSymbolicName(), null);

+        return null;

+    }

+

+    private void err(String s, Throwable e) {

+        System.err.println(s + " : " + e.getMessage());

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/ResultPrinter.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/ResultPrinter.java
new file mode 100644
index 0000000..4eb4e96
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/impl/ResultPrinter.java
@@ -0,0 +1,161 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.impl;
+
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.Enumeration;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+
+/**
+ * Result Printer.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResultPrinter implements TestListener {
+    PrintStream fWriter;
+
+    int fColumn = 0;
+
+    public ResultPrinter(PrintStream writer) {
+        fWriter = writer;
+    }
+
+    /*
+     * API for use by textui.TestRunner
+     */
+
+    synchronized void print(TestResult result, long runTime) {
+        printHeader(runTime);
+        printErrors(result);
+        printFailures(result);
+        printFooter(result);
+    }
+
+    void printWaitPrompt() {
+        getWriter().println();
+        getWriter().println("<RETURN> to continue");
+    }
+
+    /*
+     * Internal methods
+     */
+
+    protected void printHeader(long runTime) {
+        getWriter().println();
+        getWriter().println("Time: " + elapsedTimeAsString(runTime));
+    }
+
+    protected void printErrors(TestResult result) {
+        printDefects(result.errors(), result.errorCount(), "error");
+    }
+
+    protected void printFailures(TestResult result) {
+        printDefects(result.failures(), result.failureCount(), "failure");
+    }
+
+    protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
+        if (count == 0)
+            return;
+        if (count == 1)
+            getWriter().println("There was " + count + " " + type + ":");
+        else
+            getWriter().println("There were " + count + " " + type + "s:");
+        for (int i = 1; booBoos.hasMoreElements(); i++) {
+            printDefect(booBoos.nextElement(), i);
+        }
+    }
+
+    public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
+        printDefectHeader(booBoo, count);
+        printDefectTrace(booBoo);
+    }
+
+    protected void printDefectHeader(TestFailure booBoo, int count) {
+        // I feel like making this a println, then adding a line giving the throwable a chance to print something
+        // before we get to the stack trace.
+        getWriter().print(count + ") " + booBoo.failedTest());
+    }
+
+    protected void printDefectTrace(TestFailure booBoo) {
+        getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
+    }
+
+    protected void printFooter(TestResult result) {
+        if (result.wasSuccessful()) {
+            getWriter().println();
+            getWriter().print("OK");
+            getWriter().println(" (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")");
+
+        } else {
+            getWriter().println();
+            getWriter().println("FAILURES!!!");
+            getWriter().println("Tests run: " + result.runCount() + ",  Failures: " + result.failureCount() + ",  Errors: " + result.errorCount());
+        }
+        getWriter().println();
+    }
+
+    /**
+     * Returns the formatted string of the elapsed time. Duplicated from BaseTestRunner. Fix it.
+     */
+    protected String elapsedTimeAsString(long runTime) {
+        return NumberFormat.getInstance().format((double) runTime / 1000);
+    }
+
+    public PrintStream getWriter() {
+        return fWriter;
+    }
+
+    /**
+     * @see junit.framework.TestListener#addError(Test, Throwable)
+     */
+    public void addError(Test test, Throwable t) {
+        getWriter().print("E");
+    }
+
+    /**
+     * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+     */
+    public void addFailure(Test test, AssertionFailedError t) {
+        getWriter().print("F");
+    }
+
+    /**
+     * @see junit.framework.TestListener#endTest(Test)
+     */
+    public void endTest(Test test) {
+    }
+
+    /**
+     * @see junit.framework.TestListener#startTest(Test)
+     */
+    public void startTest(Test test) {
+        getWriter().print(".");
+        if (fColumn++ >= 40) {
+            getWriter().println();
+            fColumn = 0;
+        }
+    }
+
+}
diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestCase.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestCase.java
new file mode 100644
index 0000000..2ee139e
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestCase.java
@@ -0,0 +1,34 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+

+/**

+ * Simple OSGi Test Case.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class TestOSGiTestCase extends OSGiTestCase {

+    

+    public void test1() {

+        System.out.println("Test BC");

+        assertNotNull("Test bundle context", context);

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestSuite.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestSuite.java
new file mode 100644
index 0000000..c68f37c
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestOSGiTestSuite.java
@@ -0,0 +1,43 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.test;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+/**

+ * Simple OSGi Test suite.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class TestOSGiTestSuite extends TestSuite {

+    

+    public static Test suite(BundleContext bc) {

+        TestSuite ts = new TestSuite();

+        ts.setName("Test OSGi suite() method");

+        ts.addTestSuite(TestTestCase.class);

+        OSGiTestSuite ots = new OSGiTestSuite(TestOSGiTestCase.class, bc);

+        ots.setBundleContext(bc);

+        ts.addTest(ots);

+        return ts;

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestCase.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestCase.java
new file mode 100644
index 0000000..0e1527b
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestCase.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.test;

+

+import junit.framework.TestCase;

+

+/**

+ * Simple Test Case.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class TestTestCase extends TestCase {

+    

+    public void test1() { }

+    

+    public void test2() { }

+    

+    public void test3() { }

+    

+    public void test4() { }

+

+}

diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestSuite.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestSuite.java
new file mode 100644
index 0000000..6bd1bf1
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/test/TestTestSuite.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.junit4osgi.test;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+/**

+ * Simple OSGi Test Suite.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class TestTestSuite extends TestSuite {

+    

+    public static Test suite() {

+        TestSuite ts = new TestSuite();

+        ts.setName("Test suite() method");

+        ts.addTestSuite(TestTestCase.class);

+        return ts;

+    }

+

+}

diff --git a/ipojo/examples/junit4osgi/metadata.xml b/ipojo/examples/junit4osgi/metadata.xml
new file mode 100644
index 0000000..29be5f3
--- /dev/null
+++ b/ipojo/examples/junit4osgi/metadata.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO xmlns:extender="org.apache.felix.ipojo.extender">

+	<Component className="org.apache.felix.ipojo.junit4osgi.impl.JunitExtender">

+		<extender:extender extension="Test-Suite" onArrival="onBundleArrival" onDeparture="onBundleDeparture"/>

+		<callback transition="invalidate" method="stopping"/>

+		<provides/>

+	</Component>

+	<instance component="org.apache.felix.ipojo.junit4osgi.impl.JunitExtender"/>

+	

+	<component className="org.apache.felix.ipojo.junit4osgi.command.JunitCommand" factory="false">

+		<requires field="runner"/>

+		<provides/>

+	</component>

+	<instance component="org.apache.felix.ipojo.junit4osgi.command.JunitCommand"/>

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/junit4osgi/pom.xml b/ipojo/examples/junit4osgi/pom.xml
new file mode 100644
index 0000000..4e5a05e
--- /dev/null
+++ b/ipojo/examples/junit4osgi/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project>

+  <parent>

+    <groupId>ipojo.examples</groupId>

+  	<artifactId>ipojo.examples</artifactId>

+  	<version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+  <modelVersion>4.0.0</modelVersion>

+  <artifactId>Junit4Osgi</artifactId>

+  <name>Apache Felix iPOJO Junit4OSGi</name>

+  <packaging>pom</packaging>

+

+  <profiles>

+	<profile>

+		<id>java5</id>

+		<activation>

+			<jdk>1.5</jdk>

+		</activation>

+		<modules>

+			<module>junit4osgi</module>

+			<module>felix-command</module>

+			<module>swing-runner</module>

+			<module>immediate-launcher</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>java6</id>

+		<activation>

+			<jdk>1.6</jdk>

+		</activation>

+		<modules>

+			<module>junit4osgi</module>

+			<module>felix-command</module>

+			<module>swing-runner</module>

+			<module>immediate-launcher</module>

+		</modules>

+	</profile>

+  </profiles>

+</project>

diff --git a/ipojo/examples/junit4osgi/swing-runner/metadata.xml b/ipojo/examples/junit4osgi/swing-runner/metadata.xml
new file mode 100644
index 0000000..9251b6f
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/metadata.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component

+		classname="org.apache.felix.ipojo.junit4osgi.command.SwingRunner">

+		<requires field="m_runner" />

+		<callback method="stop" transition="invalidate" />

+		<callback method="start" transition="validate" />

+	</component>

+	<instance

+		component="org.apache.felix.ipojo.junit4osgi.command.SwingRunner" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/junit4osgi/swing-runner/pom.xml b/ipojo/examples/junit4osgi/swing-runner/pom.xml
new file mode 100644
index 0000000..da9bae5
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/pom.xml
@@ -0,0 +1,105 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>Junit4Osgi</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Junit4Osgi-Swing-GUI</name>

+	<artifactId>org.apache.felix.ipojo.junit4osgi.swing-gui</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>${pom.groupId}</groupId>

+			<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.shell</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>

+							iPOJO OSGi Junit Runner - Swing Gui

+						</Bundle-Name>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.junit4osgi.command

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+	<repositories>

+		<repository>

+			<id>unknown-jars-temp-repo</id>

+			<name>

+				A temporary repository created by NetBeans for libraries

+				and jars it could not identify. Please replace the

+				dependencies in this repository with correct ones and

+				delete this repository.

+			</name>

+			<url>file:${project.basedir}/lib</url>

+		</repository>

+	</repositories>

+</project>

diff --git a/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultCellRenderer.java b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultCellRenderer.java
new file mode 100644
index 0000000..680ad32
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultCellRenderer.java
@@ -0,0 +1,75 @@
+/*
+ *  Copyright 2008 clement.
+ * 
+ *  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.
+ *  under the License.
+ */
+
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.command;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+
+/**
+ * Test result renderer.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResultCellRenderer extends DefaultTableCellRenderer {
+
+    /**
+     * UUID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+
+        ResultTableModel results = (ResultTableModel) table.getModel();
+        String status = (String) results.getValueAt(row, column);
+        if (status.equals(ResultTableModel.SUCESS)) {
+            c.setForeground(Color.GREEN);
+            setToolTipText(results.getMessage(row, column));
+        }
+        if (status.equals(ResultTableModel.FAILURE)) {
+            c.setForeground(Color.ORANGE);
+            setToolTipText(results.getMessage(row, column));
+        }
+        if (status.equals(ResultTableModel.ERROR)) {
+            c.setForeground(Color.RED);
+            setToolTipText(results.getMessage(row, column));
+        }
+
+        return c;
+    }
+}
diff --git a/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultTableModel.java b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultTableModel.java
new file mode 100644
index 0000000..491f223
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/ResultTableModel.java
@@ -0,0 +1,183 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.command;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+/**
+ * Result Table Model.
+ * Store the results of executed tests.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ResultTableModel extends AbstractTableModel {
+
+    public static final String SUCESS = "success";
+
+    public static final String FAILURE = "failure";
+
+    public static final String ERROR = "error";
+
+    private static final long serialVersionUID = 1L;
+
+    private List<TestRecord> results = new ArrayList<TestRecord>();
+
+    public int getRowCount() {
+        return results.size();
+    }
+
+    public int getColumnCount() {
+        return 2;
+    }
+
+    public void addTest(Test t, AssertionFailedError e) {
+        TestRecord rec = new TestRecord(t, e);
+        results.add(rec);
+        fireTableDataChanged();
+    }
+
+    public void addTest(Test t, Throwable e) {
+        TestRecord rec = new TestRecord(t, e);
+        results.add(rec);
+        fireTableDataChanged();
+    }
+
+    public void addTest(Test t) {
+        if (!contains(t)) {
+            TestRecord rec = new TestRecord(t);
+            results.add(rec);
+            fireTableDataChanged();
+        }
+    }
+
+    public int getTestCount() {
+        return results.size();
+    }
+
+    public int getSucess() {
+        int count = 0;
+        for (TestRecord test : results) {
+            if (test.m_wasSucessFull) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    public int getErrors() {
+        int count = 0;
+        for (TestRecord test : results) {
+            if (test.m_error != null) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    public int getFailures() {
+        int count = 0;
+        for (TestRecord test : results) {
+            if (test.m_failure != null) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    private boolean contains(Test t) {
+        for (TestRecord test : results) {
+            if (test.m_test.equals(t)) { return true; }
+        }
+        return false;
+    }
+
+    public void clear() {
+        results.clear();
+        fireTableDataChanged();
+    }
+
+    public Object getValueAt(int rowIndex, int columnIndex) {
+        if (columnIndex == 0) { return results.get(rowIndex).m_test; }
+        if (columnIndex == 1) {
+            TestRecord tr = results.get(rowIndex);
+            if (tr.m_wasSucessFull) { return SUCESS; }
+            if (tr.m_failure != null) { return FAILURE; }
+            if (tr.m_error != null) { return ERROR; }
+        }
+        return null;
+    }
+
+    public String getColumnName(int column) {
+        if (column == 0) { return "Test"; }
+
+        if (column == 1) { return "Status"; }
+
+        return null;
+    }
+
+    public String getMessage(int row, int column) {
+        if (row == -1) { return null; }
+        TestRecord rec = results.get(row);
+        if (rec.m_wasSucessFull) { return "The test " + rec.m_test + " was executed sucessfully."; }
+        if (rec.m_failure != null) { return "The test " + rec.m_test + " has failed : \n" + rec.m_failure.getMessage(); }
+        if (rec.m_error != null) {
+            String message = "The test " + rec.m_test + " has thrown an error : \n" + rec.m_error.getMessage();
+            StringWriter sw = new StringWriter();
+            rec.m_error.printStackTrace(new PrintWriter(sw));
+            message += "\n" + sw.toString();
+            return message;
+        }
+        return "";
+    }
+
+    private class TestRecord {
+        private boolean m_wasSucessFull;
+
+        private Test m_test;
+
+        private AssertionFailedError m_failure;
+
+        private Throwable m_error;
+
+        public TestRecord(Test t, AssertionFailedError e) {
+            m_test = t;
+            m_wasSucessFull = false;
+            m_failure = e;
+        }
+
+        public TestRecord(Test t, Throwable e) {
+            m_test = t;
+            m_wasSucessFull = false;
+            m_error = e;
+        }
+
+        public TestRecord(Test t) {
+            m_test = t;
+            m_wasSucessFull = true;
+        }
+    }
+
+}
diff --git a/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.form b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.form
new file mode 100644
index 0000000..55cf564
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.form
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.5" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+  <NonVisualComponents>
+    <Container class="javax.swing.JDialog" name="m_resultDialog">
+      <Properties>
+        <Property name="defaultCloseOperation" type="int" value="0"/>
+        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[320, 250]"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="windowClosed" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="onDialogClosed"/>
+        <EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="onDialogClosed"/>
+      </Events>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="m_message">
+          <Properties>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+              <Border info="null"/>
+            </Property>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[300, 202]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[300, 202]"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+              <BorderConstraints direction="Center"/>
+            </Constraint>
+          </Constraints>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTextArea" name="m_messageArea">
+              <Properties>
+                <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+                  <Color blue="f0" green="f0" id="Panel.background" palette="3" red="f0" type="palette"/>
+                </Property>
+                <Property name="columns" type="int" value="20"/>
+                <Property name="editable" type="boolean" value="false"/>
+                <Property name="lineWrap" type="boolean" value="true"/>
+                <Property name="rows" type="int" value="5"/>
+                <Property name="wrapStyleWord" type="boolean" value="true"/>
+                <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[300, 250]"/>
+                </Property>
+                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[250, 200]"/>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JButton" name="m_ok">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Ok"/>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[120, 23]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_okActionPerformed"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+              <BorderConstraints direction="South"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+      </SubComponents>
+    </Container>
+  </NonVisualComponents>
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+    <Property name="title" type="java.lang.String" value="Junit Runner"/>
+    <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+      <Dimension value="[580, 580]"/>
+    </Property>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,84,0,0,2,98"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="m_panel">
+      <Properties>
+        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[580, 560]"/>
+        </Property>
+        <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[580, 566]"/>
+        </Property>
+      </Properties>
+      <Constraints>
+        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+          <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="3" insetsBottom="3" insetsRight="3" anchor="10" weightX="0.0" weightY="0.0"/>
+        </Constraint>
+      </Constraints>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="m_suiteScroll">
+          <Properties>
+            <Property name="autoscrolls" type="boolean" value="true"/>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[400, 147]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[400, 147]"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="0" gridY="0" gridWidth="4" gridHeight="2" fill="1" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="3" insetsBottom="3" insetsRight="3" anchor="10" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JList" name="m_suiteList">
+              <Properties>
+                <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+                  <Connection code="new TestListModel()" type="code"/>
+                </Property>
+                <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[250, 147]"/>
+                </Property>
+                <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[250, 147]"/>
+                </Property>
+                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[250, 147]"/>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JButton" name="m_allButton">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Select All"/>
+            <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_allButtonActionPerformed"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="3" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="m_executeButton">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Execute"/>
+            <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[90, 23]"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="m_executeButtonActionPerformed"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="4" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Container class="javax.swing.JScrollPane" name="m_resultScroll">
+          <Properties>
+            <Property name="verticalScrollBarPolicy" type="int" value="22"/>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[452, 402]"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="0" gridY="2" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="3" insetsBottom="3" insetsRight="3" anchor="10" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTable" name="m_resultTable">
+              <Properties>
+                <Property name="autoCreateRowSorter" type="boolean" value="true"/>
+                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+                  <Font name="Tahoma" size="10" style="0"/>
+                </Property>
+                <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
+                  <Connection code="new ResultTableModel()" type="code"/>
+                </Property>
+                <Property name="autoResizeMode" type="int" value="4"/>
+                <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[300, 400]"/>
+                </Property>
+                <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="[300, 400]"/>
+                </Property>
+                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+                  <Dimension value="null"/>
+                </Property>
+              </Properties>
+              <Events>
+                <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="m_resultTableMouseClicked"/>
+              </Events>
+            </Component>
+          </SubComponents>
+        </Container>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="m_statusBar">
+      <Constraints>
+        <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+          <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+        </Constraint>
+      </Constraints>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JProgressBar" name="m_progress">
+          <Properties>
+            <Property name="indeterminate" type="boolean" value="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="m_executedResults">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="aaaaaaaaaaaaaaa"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.java b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.java
new file mode 100644
index 0000000..82c4366
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/SwingRunner.java
@@ -0,0 +1,475 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.command;
+
+import java.awt.Cursor;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JScrollBar;
+
+import javax.swing.table.TableColumn;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.felix.ipojo.junit4osgi.OSGiJunitRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+
+/**
+ * Swing Runner for Junit4Osgi.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SwingRunner extends javax.swing.JFrame implements BundleListener {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Bundle context (to register the bundle listener).
+     */
+    private BundleContext m_context;
+    
+    /**
+     * OSGi Junit Runner Service. 
+     */
+    private OSGiJunitRunner m_runner;
+    
+    /**
+     * State variable describing if we are executing tests.
+     */
+    private boolean m_running = false;
+    
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton m_allButton;
+    private javax.swing.JButton m_executeButton;
+    private javax.swing.JLabel m_executedResults;
+    private javax.swing.JScrollPane m_message;
+    private javax.swing.JTextArea m_messageArea;
+    private javax.swing.JButton m_ok;
+    private javax.swing.JPanel m_panel;
+    private javax.swing.JProgressBar m_progress;
+    private javax.swing.JDialog m_resultDialog;
+    private javax.swing.JScrollPane m_resultScroll;
+    private javax.swing.JTable m_resultTable;
+    private javax.swing.JPanel m_statusBar;
+    private javax.swing.JList m_suiteList;
+    private javax.swing.JScrollPane m_suiteScroll;
+    // End of variables declaration//GEN-END:variables
+
+    /**
+     * Constructor.
+     * @param bc : bundle context.
+     */
+    public SwingRunner(BundleContext bc) {
+        m_context = bc;
+    }
+
+    /**
+     * Start method.
+     */
+    public void start() {
+        initComponents();
+        setVisible(true);
+        m_resultDialog.setVisible(false);
+        refreshSuites();
+        m_context.addBundleListener(this);
+        m_executedResults.setText(" \t No executed tests");
+        m_progress.setIndeterminate(false);
+        m_progress.setMaximum(100);
+        m_progress.setValue(100);
+        
+        TableColumn column = null;
+        for (int i = 0; i < m_resultTable.getColumnCount(); i++) {
+            column = m_resultTable.getColumnModel().getColumn(i);
+            if (i == 0) {
+                column.setPreferredWidth(350); //first column is bigger
+            } else {
+                column.setPreferredWidth(50);
+                column.setCellRenderer(new ResultCellRenderer());
+        }
+}
+    }
+
+    /**
+     * Stop method.
+     */
+    public void stop() {
+        m_context.removeBundleListener(this);
+        dispose();
+    }
+
+    /**
+     * Refresh the list of available test suites.
+     */
+    private void refreshSuites() {
+        List<Test> list = m_runner.getTests();
+        TestListModel lm = (TestListModel) m_suiteList.getModel();
+        lm.clear();
+        for (Test t : list) {
+            lm.addTest(t);
+        }
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+        java.awt.GridBagConstraints gridBagConstraints;
+
+        m_resultDialog = new javax.swing.JDialog();
+        m_message = new javax.swing.JScrollPane();
+        m_messageArea = new javax.swing.JTextArea();
+        m_ok = new javax.swing.JButton();
+        m_panel = new javax.swing.JPanel();
+        m_suiteScroll = new javax.swing.JScrollPane();
+        m_suiteList = new javax.swing.JList();
+        m_allButton = new javax.swing.JButton();
+        m_executeButton = new javax.swing.JButton();
+        m_resultScroll = new javax.swing.JScrollPane();
+        m_resultTable = new javax.swing.JTable();
+        m_statusBar = new javax.swing.JPanel();
+        m_progress = new javax.swing.JProgressBar();
+        m_executedResults = new javax.swing.JLabel();
+
+        m_resultDialog.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
+        m_resultDialog.setMinimumSize(new java.awt.Dimension(320, 250));
+        m_resultDialog.addWindowListener(new java.awt.event.WindowAdapter() {
+            public void windowClosed(java.awt.event.WindowEvent evt) {
+                onDialogClosed(evt);
+            }
+            public void windowClosing(java.awt.event.WindowEvent evt) {
+                onDialogClosed(evt);
+            }
+        });
+
+        m_message.setBorder(null);
+        m_message.setMinimumSize(new java.awt.Dimension(300, 202));
+        m_message.setPreferredSize(new java.awt.Dimension(300, 202));
+
+        m_messageArea.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));
+        m_messageArea.setColumns(20);
+        m_messageArea.setEditable(false);
+        m_messageArea.setLineWrap(true);
+        m_messageArea.setRows(5);
+        m_messageArea.setWrapStyleWord(true);
+        m_messageArea.setMinimumSize(new java.awt.Dimension(300, 250));
+        m_messageArea.setPreferredSize(new java.awt.Dimension(250, 200));
+        m_message.setViewportView(m_messageArea);
+
+        m_resultDialog.getContentPane().add(m_message, java.awt.BorderLayout.CENTER);
+
+        m_ok.setText("Ok");
+        m_ok.setPreferredSize(new java.awt.Dimension(120, 23));
+        m_ok.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                okActionPerformed(evt);
+            }
+        });
+        m_resultDialog.getContentPane().add(m_ok, java.awt.BorderLayout.SOUTH);
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        setTitle("Junit Runner");
+        setMinimumSize(new java.awt.Dimension(580, 580));
+        getContentPane().setLayout(new java.awt.GridBagLayout());
+
+        m_panel.setMinimumSize(new java.awt.Dimension(580, 560));
+        m_panel.setPreferredSize(new java.awt.Dimension(580, 566));
+        m_panel.setLayout(new java.awt.GridBagLayout());
+
+        m_suiteScroll.setAutoscrolls(true);
+        m_suiteScroll.setMinimumSize(new java.awt.Dimension(400, 147));
+        m_suiteScroll.setPreferredSize(new java.awt.Dimension(400, 147));
+
+        m_suiteList.setModel(new TestListModel());
+        m_suiteList.setMaximumSize(new java.awt.Dimension(250, 147));
+        m_suiteList.setMinimumSize(new java.awt.Dimension(250, 147));
+        m_suiteList.setPreferredSize(new java.awt.Dimension(250, 147));
+        m_suiteScroll.setViewportView(m_suiteList);
+
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 0;
+        gridBagConstraints.gridy = 0;
+        gridBagConstraints.gridwidth = 4;
+        gridBagConstraints.gridheight = 2;
+        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
+        m_panel.add(m_suiteScroll, gridBagConstraints);
+
+        m_allButton.setText("Select All");
+        m_allButton.setMaximumSize(new java.awt.Dimension(90, 23));
+        m_allButton.setMinimumSize(new java.awt.Dimension(90, 23));
+        m_allButton.setPreferredSize(new java.awt.Dimension(90, 23));
+        m_allButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                allButtonActionPerformed(evt);
+            }
+        });
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 4;
+        gridBagConstraints.gridy = 0;
+        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
+        gridBagConstraints.insets = new java.awt.Insets(3, 0, 0, 0);
+        m_panel.add(m_allButton, gridBagConstraints);
+
+        m_executeButton.setText("Execute");
+        m_executeButton.setMaximumSize(new java.awt.Dimension(90, 23));
+        m_executeButton.setMinimumSize(new java.awt.Dimension(90, 23));
+        m_executeButton.setPreferredSize(new java.awt.Dimension(90, 23));
+        m_executeButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                executeButtonActionPerformed(evt);
+            }
+        });
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 4;
+        gridBagConstraints.gridy = 1;
+        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+        gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
+        m_panel.add(m_executeButton, gridBagConstraints);
+
+        m_resultScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        m_resultScroll.setMinimumSize(new java.awt.Dimension(452, 402));
+
+        m_resultTable.setFont(new java.awt.Font("Tahoma", 0, 10));
+        m_resultTable.setModel(new ResultTableModel());
+        m_resultTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS);
+        m_resultTable.setMaximumSize(new java.awt.Dimension(300, 400));
+        m_resultTable.setMinimumSize(new java.awt.Dimension(300, 400));
+        m_resultTable.setPreferredSize(null);
+        m_resultTable.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                resultTableMouseClicked(evt);
+            }
+        });
+        m_resultScroll.setViewportView(m_resultTable);
+
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 0;
+        gridBagConstraints.gridy = 2;
+        gridBagConstraints.gridwidth = 5;
+        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+        gridBagConstraints.insets = new java.awt.Insets(2, 3, 3, 3);
+        m_panel.add(m_resultScroll, gridBagConstraints);
+
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 0;
+        gridBagConstraints.gridy = 0;
+        gridBagConstraints.gridheight = 2;
+        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
+        getContentPane().add(m_panel, gridBagConstraints);
+
+        m_statusBar.setLayout(new javax.swing.BoxLayout(m_statusBar, javax.swing.BoxLayout.LINE_AXIS));
+
+        m_progress.setIndeterminate(true);
+        m_statusBar.add(m_progress);
+
+        m_executedResults.setText("aaaaaaaaaaaaaaa");
+        m_statusBar.add(m_executedResults);
+
+        gridBagConstraints = new java.awt.GridBagConstraints();
+        gridBagConstraints.gridx = 0;
+        gridBagConstraints.gridy = 2;
+        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+        getContentPane().add(m_statusBar, gridBagConstraints);
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * Execute button action.
+     * @param evt : event.
+     */
+    private void executeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_executeButtonActionPerformed
+        if (m_running) { return; }
+        // Collect selected test.
+        int[] indices = m_suiteList.getSelectedIndices();
+        List<Test> list = new ArrayList<Test>(indices.length);
+        TestListModel model = (TestListModel) m_suiteList.getModel();
+        for (int i = 0; i < indices.length; i++) {
+            list.add(model.getTestElementAt(indices[i]));
+        }
+        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+        executeTest(list);
+    }//GEN-LAST:event_m_executeButtonActionPerformed
+
+    /**
+     * All button action.
+     * @param evt : event.
+     */
+    private void allButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_allButtonActionPerformed
+        int max = m_suiteList.getModel().getSize();
+        int[] indices = new int[max];
+        for (int i = 0; i < max; i++) {
+            indices[i] = i;
+        }
+        m_suiteList.setSelectedIndices(indices);
+    }//GEN-LAST:event_m_allButtonActionPerformed
+
+    /**
+     * Listener on table click.
+     * @param evt : event.
+     */
+    private void resultTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_m_resultTableMouseClicked
+        Point p = evt.getPoint();
+        int row = m_resultTable.rowAtPoint(p);
+        int col = m_resultTable.columnAtPoint(p);
+        ResultTableModel model = (ResultTableModel) m_resultTable.getModel();
+        String message = model.getMessage(row, col);
+        if (message != null) {
+            setEnabled(false);
+            m_resultDialog.setTitle("Test Report");
+            m_messageArea.setText(message);
+            m_resultDialog.setVisible(true);
+        }
+    }//GEN-LAST:event_m_resultTableMouseClicked
+
+    /**
+     * Ok button action.
+     * @param evt : event.
+     */
+    private void okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_m_okActionPerformed
+        m_resultDialog.setVisible(false);
+        setEnabled(true);
+    }//GEN-LAST:event_m_okActionPerformed
+
+    /**
+     * Listener when the test report is closed.
+     * @param evt : event.
+     */
+    private void onDialogClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_onDialogClosed
+        m_resultDialog.setVisible(false);
+        setEnabled(true);
+    }//GEN-LAST:event_onDialogClosed
+
+    /**
+     * Execute method.
+     * @param list : list of test to execute.
+     */
+    private void executeTest(final List<Test> list) {
+        Runnable thread = new Runnable() {
+            public void run() {
+                ResultTableModel model = (ResultTableModel) m_resultTable.getModel();
+                m_running = true;
+                m_executeButton.setText("Running...");
+                m_progress.setIndeterminate(true);
+                model.clear();
+                for (int i = 0; i < list.size(); i++) {
+                    TestResult tr = new TestResult();
+                    tr.addListener(new MyTestListener());
+                    list.get(i).run(tr);
+                }
+                m_running = false;
+                m_progress.setIndeterminate(false);
+                m_progress.setMaximum(100);
+                m_progress.setValue(100);
+                m_executeButton.setText("Execute");
+                computeExecutedTest();
+                setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+            }
+
+        };
+        new Thread(thread).start();
+    }
+    
+     private void computeExecutedTest() {
+        ResultTableModel results = (ResultTableModel) m_resultTable.getModel();
+        String m = " \t ";
+        m+= results.getTestCount() + " tests executed / ";
+        m+= results.getSucess() + " sucess / ";
+        m+= results.getFailures() + " failures / ";
+        m+= results.getErrors() + " errors ";
+        m_executedResults.setText(m);
+     }
+
+    private class MyTestListener implements junit.framework.TestListener {
+        /**
+         * Table model.
+         */
+        ResultTableModel m_model = (ResultTableModel) m_resultTable.getModel();
+
+        /**
+         * Add an error.
+         * @param arg0 : test which throws an error.
+         * @param arg1 : thrown exception.
+         * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
+         */
+        public void addError(Test arg0, Throwable arg1) {
+            m_model.addTest(arg0, arg1);
+            adjustScroll();
+        }
+
+        /**
+         * Add a failure.
+         * @param arg0 : failing test.
+         * @param arg1 : thrown failure.
+         * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
+         */
+        public void addFailure(Test arg0, AssertionFailedError arg1) {
+            m_model.addTest(arg0, arg1);
+            adjustScroll();
+        }
+
+        /**
+         * End of a test.
+         * @param arg0 : test.
+         * @see junit.framework.TestListener#endTest(junit.framework.Test)
+         */
+        public void endTest(Test arg0) {
+            m_model.addTest(arg0);
+            adjustScroll();
+        }
+
+        /**
+         * Start of a test.
+         * @param arg0 : test.
+         * @see junit.framework.TestListener#startTest(junit.framework.Test)
+         */
+        public void startTest(Test arg0) {
+            // Nothing to do here.
+        }
+
+        /**
+         * Adjust the scrolling bar of the result table.
+         */
+        private void adjustScroll() {
+            JScrollBar bar = m_resultScroll.getVerticalScrollBar();
+            if ((bar != null) && (bar.isVisible())) {
+                bar.setValue(Integer.MAX_VALUE);
+            }
+        }
+
+    }
+
+    /**
+     * Bundle Changed callback method.
+     * @param arg0 : bundle event.
+     * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+     */
+    public void bundleChanged(BundleEvent arg0) {
+        refreshSuites();
+    }
+
+}
diff --git a/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/TestListModel.java b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/TestListModel.java
new file mode 100644
index 0000000..4811c5e
--- /dev/null
+++ b/ipojo/examples/junit4osgi/swing-runner/src/main/java/org/apache/felix/ipojo/junit4osgi/command/TestListModel.java
@@ -0,0 +1,89 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.command;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.AbstractListModel;
+import junit.framework.Test;
+
+/**
+ * Test Suite list model.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestListModel extends AbstractListModel {
+
+    private static final long serialVersionUID = 1L;
+
+    private List<TestRecord> list = new ArrayList<TestRecord>();
+
+    public Object getElementAt(int index) {
+        if (index >= list.size()) {
+            return null;
+        } else {
+            return list.get(index).name;
+        }
+    }
+
+    public Test getTestElementAt(int index) {
+        return list.get(index).test;
+    }
+
+    public void addTest(Test test) {
+        synchronized(this) {
+            TestRecord tr = new TestRecord();
+            tr.test = test;
+            tr.name = test.toString();
+            list.add(tr);
+        }
+        fireContentsChanged(this, list.size() - 1, list.size() - 1);
+    }
+
+    public void removeTest(Test test) {
+        int index = 1;
+        synchronized(this) {
+            for (TestRecord t : list) {
+                if (t.test.equals(test)) {
+                    index = list.indexOf(t);
+                    list.remove(t);
+                    return;
+                }
+            }
+        }
+        
+        if (index != -1) {
+            fireContentsChanged(this, index, index);
+        }
+    }
+
+    public void clear() {
+        list.clear();
+    }
+
+    private class TestRecord {
+        public Test test;
+
+        public String name;
+    }
+
+    public int getSize() {
+        return list.size();
+    }
+
+}
diff --git a/ipojo/examples/pom.xml b/ipojo/examples/pom.xml
new file mode 100644
index 0000000..0aef7eb
--- /dev/null
+++ b/ipojo/examples/pom.xml
@@ -0,0 +1,40 @@
+<project>

+  <parent>

+    <groupId>org.apache.felix</groupId>

+    <artifactId>iPOJO</artifactId>

+    <version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+

+  <modelVersion>4.0.0</modelVersion>

+  <groupId>ipojo.examples</groupId>

+  <artifactId>ipojo.examples</artifactId>

+  <name>Apache Felix iPOJO Examples</name>

+  <packaging>pom</packaging>

+  <modules>

+	<module>tutorial-maven</module>

+  </modules>

+  

+  <profiles>

+	<profile>

+		<id>java5</id>

+		<activation>

+			<jdk>1.5</jdk>

+		</activation>

+		<modules>

+			<module>junit4osgi</module>

+			<module>property-handler</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>java6</id>

+		<activation>

+			<jdk>1.6</jdk>

+		</activation>

+		<modules>

+			<module>junit4osgi</module>

+			<module>property-handler</module>

+		</modules>

+	</profile>

+  </profiles>

+</project>
\ No newline at end of file
diff --git a/ipojo/examples/property-handler/PropertyHandler/metadata.xml b/ipojo/examples/property-handler/PropertyHandler/metadata.xml
new file mode 100644
index 0000000..48d7bef
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandler/metadata.xml
@@ -0,0 +1,9 @@
+<ipojo xmlns:props="example.handler.properties">

+

+	<!-- Declare the handler -->

+	<handler name="properties" namespace="example.handler.properties"

+		classname="org.apache.felix.ipojo.handler.properties.PropertiesHandler">

+		<!--  the properties handler does not use any other handler -->

+	</handler>

+

+</ipojo>

diff --git a/ipojo/examples/property-handler/PropertyHandler/pom.xml b/ipojo/examples/property-handler/PropertyHandler/pom.xml
new file mode 100644
index 0000000..d806ab9
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandler/pom.xml
@@ -0,0 +1,85 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>ipojo.examples.property.handler</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Property Handler</name>

+	<artifactId>

+		org.apache.felix.ipojo.example.handler.property

+	</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Private-Package>

+							org.apache.felix.ipojo.handler.properties,

+							example.handler.properties

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/property-handler/PropertyHandler/src/main/java/example/handler/properties/Properties.java b/ipojo/examples/property-handler/PropertyHandler/src/main/java/example/handler/properties/Properties.java
new file mode 100644
index 0000000..9144bb8
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandler/src/main/java/example/handler/properties/Properties.java
@@ -0,0 +1,33 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package example.handler.properties;

+

+/**

+ * The Properties annotation.

+ * This annotation may be used in POJO class to used the Property handler.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public @interface Properties {

+    

+    /**

+     * Returns the property file used by the handler.

+     */

+    String file();

+

+}

diff --git a/ipojo/examples/property-handler/PropertyHandler/src/main/java/org/apache/felix/ipojo/handler/properties/PropertiesHandler.java b/ipojo/examples/property-handler/PropertyHandler/src/main/java/org/apache/felix/ipojo/handler/properties/PropertiesHandler.java
new file mode 100644
index 0000000..abd3583
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandler/src/main/java/org/apache/felix/ipojo/handler/properties/PropertiesHandler.java
@@ -0,0 +1,283 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.properties;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.util.Dictionary;

+import java.util.Enumeration;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.FieldMetadata;

+import org.apache.felix.ipojo.parser.PojoMetadata;

+

+/**

+ * This handler load a properties file containing property value. The handler injects this values inside fields. When stopping the handler stores

+ * updated value inside the file. The properties file contains [field-name: field-value] (field-value are strings) Metadata :

+ * &lt;example.handler.properties:properties file="file-path"&gt; Instances can override file locations by setting the properties.file property.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class PropertiesHandler extends PrimitiveHandler {

+    

+    /** The Handler NAMESPACE. */

+    private final String NAMESPACE = "example.handler.properties";

+

+    /** Properties file. */

+    private Properties m_properties = new Properties();

+

+    /** File location. */

+    private String m_file;

+

+    /**

+     * This method is the first to be invoked. This method aims to configure the handler. It receives the component type metadata and the instance

+     * description. The method parses given metadata and register field to listen. Step 3 : when the instance configuration contains the

+     * properties.file property, it overrides the properties file location.

+     * @param metadata : component type metadata

+     * @param configuration : instance description

+     * @throws ConfigurationException : the configuration of the handler has failed.

+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

+    @SuppressWarnings("unchecked")

+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {

+        // Parse metadata to get <properties file="$file"/>

+

+        Element[] elem = metadata.getElements("properties", NAMESPACE); // Get all example.handler.properties:properties element

+

+        switch (elem.length) {

+            case 0:

+                // No matching element in metadata, throw a configuration error.

+                throw new ConfigurationException("No properties found");

+            case 1:

+                // One 'properties' found, get attributes.

+                m_file = elem[0].getAttribute("file");

+                if (m_file == null) {

+                    // if file is null, throw a configuration error.

+                    throw new ConfigurationException("Malformed properties element : file attribute must be set");

+                }

+                break;

+            default:

+                // To simplify we handle only one properties element.

+                throw new ConfigurationException("Only one properties element is supported");

+        }

+

+        // Look if the instance overrides file location :

+        String instanceFile = (String) configuration.get("properties.file");

+        if (instanceFile != null) {

+            m_file = instanceFile;

+        }

+

+        // Load properties

+        try {

+            loadProperties();

+        } catch (IOException e) {

+            throw new ConfigurationException("Error when reading the " + m_file + " file : " + e.getMessage());

+        }

+

+        // Register fields

+        // By convention, properties file entry are field name, so look for each property to get field list.

+

+        //First get Pojo Metadata metadata :

+        PojoMetadata pojoMeta = getPojoMetadata();

+        Enumeration e = m_properties.keys();

+        while (e.hasMoreElements()) {

+            String field = (String) e.nextElement();

+            FieldMetadata fm = pojoMeta.getField(field);

+

+            if (fm == null) { // The field does not exist

+                throw new ConfigurationException("The field " + field + " is declared in the properties file but does not exist in the pojo");

+            }

+

+            // Then check that the field is a String field

+            if (!fm.getFieldType().equals(String.class.getName())) {

+                throw new ConfigurationException("The field " + field + " exists in the pojo, but is not a String");

+            }

+

+            // All checks are ok, register the interceptor.

+            getInstanceManager().register(fm, this);

+        }

+

+        // Finally register the field to listen 

+    }

+

+    /**

+     * This method is called when the instance start (after the configure method). We just print stored properties.

+     * @see org.apache.felix.ipojo.Handler#start()

+     */

+    public void start() {

+        // The properties are already loaded (in the configure method), just print values.

+        m_properties.list(System.out);

+    }

+

+    /**

+     * This method is called when the instance stops. We save the properties to not lost the instance state and clear the stored properties.

+     * @see org.apache.felix.ipojo.Handler#stop()

+     */

+    public void stop() {

+        try {

+            saveProperties();

+        } catch (IOException e) {

+            error("Cannot read the file : " + m_file, e); // Log an error message by using the iPOJO logger

+        }

+        m_properties = null;

+    }

+

+    /**

+     * This method is called at each time the pojo 'get' a listened field. The method return the stored value.

+     * @param pojo : pojo object getting the field

+     * @param field : field name.

+     * @param o : previous value.

+     * @return the stored value.

+     * @see org.apache.felix.ipojo.PrimitiveHandler#getterCallback(java.lang.String, java.lang.Object)

+     */

+    public Object onGet(Object pojo, String field, Object o) {

+        // When the pojo requires a value for a managed field, this method is invoked.

+        // So, we have just to return the stored value.

+        return m_properties.get(field);

+    }

+

+    /**

+     * This method is called at each time the pojo 'set' a listened field. This method updates the local properties.

+     * @param pojo : pojo object setting the field

+     * @param field : field name

+     * @param newvalue : new value

+     * @see org.apache.felix.ipojo.PrimitiveHandler#setterCallback(java.lang.String, java.lang.Object)

+     */

+    public void onSet(Object pojo, String field, Object newvalue) {

+        // When the pojo set a value to a managed field, this method is invoked.

+        // So, we update the stored value.

+        m_properties.put(field, newvalue);

+    }

+

+    /**

+     * Step 2 : state properties when the instance becomes invalid.

+     * @param newState : the instance state

+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)

+     */

+    public void stateChanged(int newState) {

+        // This method is invoked each times that the instance state changed.

+

+        // If the new state is invalid, save the properties.

+        if (newState == ComponentInstance.INVALID) {

+            // Reload properties

+            try {

+                saveProperties();

+            } catch (IOException e) {

+                error("Cannot read the file : " + m_file, e); // Log an error message by using the iPOJO logger

+            }

+            return;

+        }

+    }

+

+    /**

+     * Step 5 : dynamic reconfiguration. This method is call when the instance is reconfigured externally. The given property contains property value.

+     * @param dict : new properties

+     * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)

+     */

+    @SuppressWarnings("unchecked")

+    public synchronized void reconfigure(Dictionary dict) {

+        // For each property, look if a new value is contained in the new configuration.

+        Enumeration e = m_properties.keys();

+        while (e.hasMoreElements()) {

+            String field = (String) e.nextElement();

+            String value = (String) dict.get(field);

+            // If the dictionary contains a value, update the stored value.

+            if (value != null) {

+                m_properties.put(field, value);

+            }

+        }

+    }

+

+    /**

+     * Returns handler description.

+     * @return the handler description.

+     * @see org.apache.felix.ipojo.Handler#getDescription()

+     */

+    public HandlerDescription getDescription() {

+        return new Description(this);

+    }

+

+    /**

+     * Helper method just loading the properties.

+     * @throws IOException : the file cannot be read.

+     */

+    private void loadProperties() throws IOException {

+        // Load the properties file from file system

+        File file = new File(m_file);

+        InputStream is = new FileInputStream(file);

+        m_properties.load(is);

+    }

+

+    /**

+     * Helper method writing properties.

+     * @throws IOException : the file cannot be written.

+     */

+    private void saveProperties() throws IOException {

+        // Store the file, modified the last modification date.

+        File file = new File(m_file);

+        OutputStream os = new FileOutputStream(file);

+        m_properties.store(os, "");

+    }

+

+    /**

+     * Step 3 : The handler will participate to the instance architecture. 

+     * This class describing the handler.

+     */

+    private class Description extends HandlerDescription {

+

+        /**

+         * Instantiates a new description.

+         * @param h the h

+         */

+        public Description(PrimitiveHandler h) {

+            super(h);

+        }

+

+        /**

+         * This method must return the Element describing the handler. The description of this handler contains the list of properties with attached

+         * value.

+         * @return the description of the handler.

+         * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()

+         */

+        @SuppressWarnings("unchecked")

+        public Element getHandlerInfo() {

+            Element elem = super.getHandlerInfo(); // This method must be called to get the root description element.

+            Enumeration e = m_properties.keys();

+            while (e.hasMoreElements()) {

+                String field = (String) e.nextElement();

+                Element prop = new Element("property", ""); // Create an element for the actual property.

+                // Add two attribute (the field and the value).

+                prop.addAttribute(new Attribute("field", field));

+                prop.addAttribute(new Attribute("value", (String) m_properties.get(field)));

+                elem.addElement(prop); // Attach the current element to the root element.

+            }

+            return elem;

+        }

+

+    }

+}

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/metadata.xml b/ipojo/examples/property-handler/PropertyHandlerTest/metadata.xml
new file mode 100644
index 0000000..dcc9c16
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/metadata.xml
@@ -0,0 +1,21 @@
+<ipojo xmlns:props="example.handler.properties">

+

+	<!-- Declare a component using your handler -->

+	<component

+		classname="org.apache.felix.ipojo.handler.properties.example.PropertiesTester">

+		<callback transition="validate" method="start" />

+		<callback transition="invalidate" method="stop" />

+		<!--  declare our handler -->

+		<props:properties file="props\properties.txt" />

+	</component>

+

+	<!-- Declare an instance -->

+	<instance component="annotationTester" />

+	<instance

+		component="org.apache.felix.ipojo.handler.properties.example.PropertiesTester"

+		name="i1">

+		<property name="properties.file"

+			value="props\properties-i1.txt" />

+	</instance>

+

+</ipojo>

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/pom.xml b/ipojo/examples/property-handler/PropertyHandlerTest/pom.xml
new file mode 100644
index 0000000..dc28218
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/pom.xml
@@ -0,0 +1,83 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.examples</groupId>

+		<artifactId>ipojo.examples.property.handler</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Property Handler Test</name>

+	<artifactId>

+		org.apache.felix.ipojo.example.handler.property.test

+	</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.annotations</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>

+				org.apache.felix.ipojo.example.handler.property

+			</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Private-Package>

+							org.apache.felix.ipojo.handler.properties.example

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/props/properties-i1.txt b/ipojo/examples/property-handler/PropertyHandlerTest/props/properties-i1.txt
new file mode 100644
index 0000000..7d688d2
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/props/properties-i1.txt
@@ -0,0 +1,4 @@
+#

+#Sun Nov 18 20:33:54 CET 2007

+m_property2=foo - 18 nov. 2007 20\:32\:55 - 18 nov. 2007 20\:33\:51

+m_property1=bar - 18 nov. 2007 20\:32\:55 - 18 nov. 2007 20\:33\:51

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/props/properties.txt b/ipojo/examples/property-handler/PropertyHandlerTest/props/properties.txt
new file mode 100644
index 0000000..2d46de8
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/props/properties.txt
@@ -0,0 +1,4 @@
+#

+#Sun Nov 18 20:33:54 CET 2007

+m_property2=prop2 - 18 nov. 2007 20\:32\:55 - 18 nov. 2007 20\:33\:51

+m_property1=prop1 - 18 nov. 2007 20\:32\:55 - 18 nov. 2007 20\:33\:51

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/AnnotationPropertiesTester.java b/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/AnnotationPropertiesTester.java
new file mode 100644
index 0000000..0f3df8d
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/AnnotationPropertiesTester.java
@@ -0,0 +1,83 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.properties.example;

+

+import java.text.DateFormat;

+import java.util.Date;

+

+import org.apache.felix.ipojo.annotations.Component;

+import org.apache.felix.ipojo.annotations.Invalidate;

+import org.apache.felix.ipojo.annotations.Validate;

+

+import example.handler.properties.Properties;

+

+/**

+ * A simple component implementation using the property handler.

+ *@author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+@Component(name = "annotationTester")

+@Properties(file = "props\\properties.txt")

+public class AnnotationPropertiesTester {

+ 

+    /**

+     * Property 1 : injected. 

+     */

+    private String m_property1;

+

+    /**

+     * Property 1 : injected. 

+     */

+    private String m_property2;

+

+    /**

+     * Start method : 

+     * displays loaded & injected properties before modifying them.

+     */

+    @Validate

+    public void start() {

+        System.out.println("AnnotationPropertiesTester is starting ...");

+        System.out.println("Property 1 : " + m_property1);

+        System.out.println("Property 2 : " + m_property2);

+

+        updateProperties();

+    }

+

+    /**

+     * Stop method :

+     * displays properties values.

+     */

+    @Invalidate

+    public void stop() {

+        System.out.println("AnnotationPropertiesTester is stopping ...");

+        System.out.println("Property 1 : " + m_property1);

+        System.out.println("Property 2 : " + m_property2);

+    }

+

+    /**

+     * Update property value.

+     */

+    private void updateProperties() {

+        System.out.println("Update properties");

+        Date date = new Date();

+        DateFormat df = DateFormat.getDateTimeInstance();

+        m_property1 = m_property1 + " - " + df.format(date);

+        m_property2 = m_property2 + " - " + df.format(date);

+

+    }

+}

diff --git a/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/PropertiesTester.java b/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/PropertiesTester.java
new file mode 100644
index 0000000..37872db
--- /dev/null
+++ b/ipojo/examples/property-handler/PropertyHandlerTest/src/main/java/org/apache/felix/ipojo/handler/properties/example/PropertiesTester.java
@@ -0,0 +1,68 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.properties.example;

+

+import java.text.DateFormat;

+import java.util.Date;

+

+public class PropertiesTester {

+    

+    // These two fields will be injected. 

+    private String property1;

+    private String property2;

+    

+    /**

+     * Starting method.

+     * This method will be called when the instance starts.

+     */

+    public void start() {

+        System.out.println("PropertiesTester is starting ...");

+        // Read the injected properties.

+        System.out.println("Property 1 : " + property1);

+        System.out.println("Property 2 : " + property2);

+        

+        // Update the properties.

+        updateProperties();

+    }

+    

+    /**

+     * Stopping method.

+     * This method will be called when the instance stops.

+     */

+    public void stop() {

+        System.out.println("PropertiesTester is stopping ...");

+        System.out.println("Property 1 : " + property1);

+        System.out.println("Property 2 : " + property2);

+    }

+

+    /**

+     * This method just updates managed properties.

+     * It appends the current date to the actual property value.

+     */

+    private void updateProperties() {

+        System.out.println("Update properties");

+       Date date = new Date();

+       DateFormat df = DateFormat.getDateTimeInstance();

+       // The properties will be updated in the property file

+       property1 = property1 + " - " + df.format(date);

+       property2 = property2 + " - " + df.format(date);

+        

+    }

+

+}

diff --git a/ipojo/examples/property-handler/pom.xml b/ipojo/examples/property-handler/pom.xml
new file mode 100644
index 0000000..2b9f2df
--- /dev/null
+++ b/ipojo/examples/property-handler/pom.xml
@@ -0,0 +1,36 @@
+<project>

+ <parent>

+    <groupId>ipojo.examples</groupId>

+  	<artifactId>ipojo.examples</artifactId>

+  	<version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+

+  <modelVersion>4.0.0</modelVersion>

+  <artifactId>ipojo.examples.property.handler</artifactId>

+  <name>Apache Felix iPOJO Property Handler</name>

+  <packaging>pom</packaging>

+

+  <profiles>

+	<profile>

+		<id>java5</id>

+		<activation>

+			<jdk>1.5</jdk>

+		</activation>

+		<modules>

+			<module>PropertyHandler</module>

+			<module>PropertyHandlerTest</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>java6</id>

+		<activation>

+			<jdk>1.6</jdk>

+		</activation>

+		<modules>

+			<module>PropertyHandler</module>

+			<module>PropertyHandlerTest</module>

+		</modules>

+	</profile>

+  </profiles>

+</project>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.client.annotation/metadata.xml b/ipojo/examples/tutorial-maven/hello.client.annotation/metadata.xml
new file mode 100644
index 0000000..134250d
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client.annotation/metadata.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+  <instance component="AnnotatedHelloClient" name="HelloClient"/>

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.client.annotation/pom.xml b/ipojo/examples/tutorial-maven/hello.client.annotation/pom.xml
new file mode 100644
index 0000000..eee6444
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client.annotation/pom.xml
@@ -0,0 +1,66 @@
+<project>

+  <modelVersion>4.0.0</modelVersion>

+  <packaging>bundle</packaging>

+  <groupId>ipojo.examples</groupId>

+  <artifactId>hello.client.annotation</artifactId>

+   <version>0.7.6-SNAPSHOT</version>

+  <name>Hello Service Client using Annotations</name>

+  

+  <dependencies>

+    <dependency>

+      <groupId>ipojo.examples</groupId>

+      <artifactId>hello.service</artifactId>

+      <version>${pom.version}</version>

+    </dependency>

+    <dependency>

+      <groupId>org.apache.felix</groupId>

+      <artifactId>org.apache.felix.ipojo.annotations</artifactId>

+      <version>0.7.6-SNAPSHOT</version>

+    </dependency>

+  </dependencies>

+  

+  <pluginRepositories>

+    <pluginRepository>

+      <id>apache.snapshots</id>

+      <name>snapshot plugins</name>

+      <url>

+        http://people.apache.org/repo/m2-snapshot-repository

+      </url>

+    </pluginRepository>

+  </pluginRepositories>

+  

+  <build>

+    <plugins>

+     <plugin>

+		<groupId>org.apache.maven.plugins</groupId>

+		<artifactId>maven-compiler-plugin</artifactId>

+		<configuration>

+		<source>1.5</source>

+		<target>1.5</target>

+		</configuration>

+	  </plugin>

+      <plugin>

+        <groupId>org.apache.felix</groupId>

+        <artifactId>maven-bundle-plugin</artifactId>

+        <extensions>true</extensions>

+        <configuration>

+          <instructions>

+            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>

+            <Private-Package>ipojo.example.hello.client</Private-Package>

+          </instructions>

+        </configuration>

+      </plugin>

+      <plugin>

+	      <groupId>org.apache.felix</groupId>

+	      <artifactId>maven-ipojo-plugin</artifactId>

+		  <executions>

+          	<execution>

+            	<goals>

+	              <goal>ipojo-bundle</goal>

+               </goals>

+          </execution>

+        </executions>

+      </plugin>

+    </plugins>

+  </build>

+</project>

diff --git a/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/hello/client/HelloClient.java b/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/hello/client/HelloClient.java
new file mode 100644
index 0000000..2c3697c
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/hello/client/HelloClient.java
@@ -0,0 +1,90 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package ipojo.example.hello.client;

+

+import ipojo.example.hello.Hello;

+

+import org.apache.felix.ipojo.annotations.Component;

+import org.apache.felix.ipojo.annotations.Invalidate;

+import org.apache.felix.ipojo.annotations.Requires;

+import org.apache.felix.ipojo.annotations.Validate;

+

+/**

+ * A simple Hello service client. This client use annotation instead of XML metadata.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+@Component(name = "AnnotatedHelloClient", architecture = true)

+public class HelloClient implements Runnable {

+    

+    /** Delay between two invocations. */

+    private static final int DELAY = 10000;

+

+    /**

+     * Hello services. Injected by the container.

+     */

+    @Requires

+    private Hello[] m_hello;

+

+    /**

+     *  End flag.

+     */

+    private boolean m_end;

+

+    /**

+     * Run method.

+     * @see java.lang.Runnable#run()

+     */

+    public void run() {

+        while (!m_end) {

+            try {

+                invokeHelloServices();

+                Thread.sleep(DELAY);

+            } catch (InterruptedException ie) {

+                /* will recheck end */

+            }

+        }

+    }

+

+    /**

+     * Invoke hello services.

+     */

+    public void invokeHelloServices() {

+        for (int i = 0; i < m_hello.length; i++) {

+            System.out.println(i + " :" + m_hello[i].sayHello("Clement"));

+        }

+    }

+

+    /**

+     * Starting.

+     */

+    @Validate

+    public void starting() {

+        Thread thread = new Thread(this);

+        m_end = false;

+        thread.start();

+    }

+

+    /**

+     * Stopping.

+     */

+    @Invalidate

+    public void stopping() {

+        m_end = true;

+    }

+}

diff --git a/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/source.txt b/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/source.txt
new file mode 100644
index 0000000..0198756
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client.annotation/src/main/java/ipojo/example/source.txt
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.client/metadata.xml b/ipojo/examples/tutorial-maven/hello.client/metadata.xml
new file mode 100644
index 0000000..4141c34
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client/metadata.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component className="ipojo.example.hello.client.HelloClient"

+		architecture="true">

+		<requires field="m_hello" />

+		<callback transition="validate" method="starting" />

+		<callback transition="invalidate" method="stopping" />

+		<properties>

+			<property field="m_name" name="name" />

+		</properties>

+	</component>

+	<instance component="ipojo.example.hello.client.HelloClient">

+		<property name="name" value="clement" />

+	</instance>

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.client/pom.xml b/ipojo/examples/tutorial-maven/hello.client/pom.xml
new file mode 100644
index 0000000..91cbe69
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client/pom.xml
@@ -0,0 +1,82 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging><!-- Use the BND Maven plug-in -->

+	<groupId>ipojo.examples</groupId>

+	<artifactId>hello.client</artifactId>

+	<version>0.7.6-SNAPSHOT</version>

+	<name>Hello Service Client</name>

+	<dependencies>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>hello.service</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+	</dependencies>

+

+	<pluginRepositories>

+		<pluginRepository>

+			<id>apache.snapshots</id>

+			<name>snapshot plugins</name>

+			<url>

+				http://people.apache.org/repo/m2-snapshot-repository

+			</url>

+			<releases>

+				<enabled>false</enabled>

+			</releases>

+			<snapshots>

+				<enabled>true</enabled>

+			</snapshots>

+		</pluginRepository>

+	</pluginRepositories>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<extensions>true</extensions>

+				<version>1.4.0</version>

+				<configuration>

+					<instructions>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							ipojo.example.hello.client

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>0.7.6-SNAPSHOT</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/hello/client/HelloClient.java b/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/hello/client/HelloClient.java
new file mode 100644
index 0000000..023db3f
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/hello/client/HelloClient.java
@@ -0,0 +1,90 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package ipojo.example.hello.client;

+

+import ipojo.example.hello.Hello;

+

+/**

+ * Hello Service simple client.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class HelloClient implements Runnable {

+

+    /**

+     *  Delay between two invocations. 

+     */

+    private static final int DELAY = 10000;

+    

+    /** 

+     * Hello services. 

+     * Injected by the container.

+     * */

+    private Hello[] m_hello; // Service Requirement

+

+    /** 

+     * End flag.

+     *  */

+    private boolean m_end;

+

+    /** 

+     * Name property.

+     * Injected by the container.

+     * */

+    private String m_name;

+

+    /**

+     * Run method.

+     * @see java.lang.Runnable#run()

+     */

+    public void run() {

+        while (!m_end) {

+            try {

+                invokeHelloServices();

+                Thread.sleep(DELAY);

+            } catch (InterruptedException ie) {

+                /* will recheck end */

+            }

+        }

+    }

+

+    /**

+     * Invoke hello services.

+     */

+    public void invokeHelloServices() {

+        for (int i = 0; i < m_hello.length; i++) {

+            System.out.println(m_hello[i].sayHello(m_name));

+        }

+    }

+

+    /**

+     * Starting.

+     */

+    public void starting() {

+        Thread thread = new Thread(this);

+        m_end = false;

+        thread.start();

+    }

+

+    /**

+     * Stopping.

+     */

+    public void stopping() {

+        m_end = true;

+    }

+}

diff --git a/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/source.txt b/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/source.txt
new file mode 100644
index 0000000..0198756
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.client/src/main/java/ipojo/example/source.txt
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.impl.annotation/pom.xml b/ipojo/examples/tutorial-maven/hello.impl.annotation/pom.xml
new file mode 100644
index 0000000..2281a57
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl.annotation/pom.xml
@@ -0,0 +1,88 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<groupId>ipojo.examples</groupId>

+	<artifactId>hello.impl.annotation</artifactId>

+	<version>0.7.6-SNAPSHOT</version>

+	<name>Hello Service Provider using Annotations</name>

+

+	<pluginRepositories>

+		<pluginRepository>

+			<id>apache.snapshots</id>

+			<name>snapshot plugins</name>

+			<url>

+				http://people.apache.org/repo/m2-snapshot-repository

+			</url>

+		</pluginRepository>

+	</pluginRepositories>

+

+	<dependencies>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>hello.service</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.annotations</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							ipojo.example.hello.impl

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/HelloImpl.java b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/HelloImpl.java
new file mode 100644
index 0000000..8b37c2f
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/HelloImpl.java
@@ -0,0 +1,42 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package ipojo.example.hello.impl;

+

+import ipojo.example.hello.Hello;

+

+import org.apache.felix.ipojo.annotations.Component;

+import org.apache.felix.ipojo.annotations.Provides;

+

+/**

+ * Component implementing the Hello service.

+ * This class used annotations to describe the component type. 

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+@Component

+@Provides

+public class HelloImpl implements Hello {

+    

+    /**

+     * Returns an 'Hello' message.

+     * @param name : name

+     * @return Hello message

+     * @see ipojo.example.hello.Hello#sayHello(java.lang.String)

+     */

+    public String sayHello(String name) { return "hello " + name + " @";  }

+}

diff --git a/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/source.txt b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/source.txt
new file mode 100644
index 0000000..0198756
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/java/ipojo/example/hello/impl/source.txt
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/resources/metadata.xml b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/resources/metadata.xml
new file mode 100644
index 0000000..559b556
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl.annotation/src/main/resources/metadata.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<instance component="ipojo.example.hello.impl.HelloImpl"

+		name="HelloService2" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.impl/metadata.xml b/ipojo/examples/tutorial-maven/hello.impl/metadata.xml
new file mode 100644
index 0000000..59d9666
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl/metadata.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component className="ipojo.example.hello.impl.HelloImpl"

+		name="HelloProvider" architecture="true">

+		<provides />

+	</component>

+	<instance component="HelloProvider" name="HelloService" />

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.impl/pom.xml b/ipojo/examples/tutorial-maven/hello.impl/pom.xml
new file mode 100644
index 0000000..3cf4551
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl/pom.xml
@@ -0,0 +1,65 @@
+<project>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<groupId>ipojo.examples</groupId>

+	<artifactId>hello.impl</artifactId>

+	<version>0.7.6-SNAPSHOT</version>

+	<name>Hello Service Provider</name>

+

+	<pluginRepositories>

+		<pluginRepository>

+			<id>apache.snapshots</id>

+			<name>snapshot plugins</name>

+			<url>

+				http://people.apache.org/repo/m2-snapshot-repository

+			</url>

+			<releases>

+				<enabled>false</enabled>

+			</releases>

+			<snapshots>

+				<enabled>true</enabled>

+			</snapshots>

+		</pluginRepository>

+	</pluginRepositories>

+

+	<dependencies>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>hello.service</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							ipojo.example.hello.impl

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>0.7.6-SNAPSHOT</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/HelloImpl.java b/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/HelloImpl.java
new file mode 100644
index 0000000..8008fa9
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/HelloImpl.java
@@ -0,0 +1,36 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package ipojo.example.hello.impl;

+

+import ipojo.example.hello.Hello;

+

+/**

+ * Component implementing the Hello service.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class HelloImpl implements Hello {

+    

+    /**

+     * Returns an 'Hello' message.

+     * @param name : name

+     * @return Hello message

+     * @see ipojo.example.hello.Hello#sayHello(java.lang.String)

+     */

+    public String sayHello(String name) { return "hello " + name;  }

+}

diff --git a/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/source.txt b/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/source.txt
new file mode 100644
index 0000000..0198756
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.impl/src/main/java/ipojo/example/hello/impl/source.txt
@@ -0,0 +1 @@
+PUT YOUR SOURCE FILES HERE
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.service/metadata.xml b/ipojo/examples/tutorial-maven/hello.service/metadata.xml
new file mode 100644
index 0000000..89547bc
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.service/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+  <component className="ipojo.example.hello.impl.HelloImpl" name="HelloProvider" architecture="true">

+    <provides/>

+  </component>

+  <instance component="HelloProvider" name="HelloService"/>

+</iPOJO>
\ No newline at end of file
diff --git a/ipojo/examples/tutorial-maven/hello.service/pom.xml b/ipojo/examples/tutorial-maven/hello.service/pom.xml
new file mode 100644
index 0000000..084989d
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.service/pom.xml
@@ -0,0 +1,63 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<groupId>ipojo.examples</groupId>

+	<artifactId>hello.service</artifactId>

+	<version>0.7.6-SNAPSHOT</version>

+	<name>Hello Service</name>

+

+	<pluginRepositories>

+		<pluginRepository>

+			<id>apache.snapshots</id>

+			<name>snapshot plugins</name>

+			<url>

+				http://people.apache.org/repo/m2-snapshot-repository

+			</url>

+			<releases>

+				<enabled>false</enabled>

+			</releases>

+			<snapshots>

+				<enabled>true</enabled>

+			</snapshots>

+		</pluginRepository>

+	</pluginRepositories>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Export-Package>

+							ipojo.example.hello

+						</Export-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/examples/tutorial-maven/hello.service/src/main/java/ipojo/example/hello/Hello.java b/ipojo/examples/tutorial-maven/hello.service/src/main/java/ipojo/example/hello/Hello.java
new file mode 100644
index 0000000..e0c25da
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/hello.service/src/main/java/ipojo/example/hello/Hello.java
@@ -0,0 +1,33 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package ipojo.example.hello;

+

+/**

+ * Hello Interface.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public interface Hello {

+

+    /**

+     * Returns a message like: "Hello $user_name".

+     * @param name the name

+     * @return the hello message

+     */

+    String sayHello(String name);

+}

diff --git a/ipojo/examples/tutorial-maven/pom.xml b/ipojo/examples/tutorial-maven/pom.xml
new file mode 100644
index 0000000..99d12ac
--- /dev/null
+++ b/ipojo/examples/tutorial-maven/pom.xml
@@ -0,0 +1,40 @@
+<project>

+  <parent>

+    <groupId>ipojo.examples</groupId>

+  	<artifactId>ipojo.examples</artifactId>

+  	<version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+  <modelVersion>4.0.0</modelVersion>

+  <artifactId>ipojo.tutorial</artifactId>

+  <name>Apache Felix iPOJO Tutorial</name>

+  <packaging>pom</packaging>

+  <modules>

+	<module>hello.service</module>

+	<module>hello.impl</module>

+	<module>hello.client</module>

+  </modules>

+  

+  <profiles>

+	<profile>

+		<id>java5</id>

+		<activation>

+			<jdk>1.5</jdk>

+		</activation>

+		<modules>

+			<module>hello.impl.annotation</module>

+			<module>hello.client.annotation</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>java6</id>

+		<activation>

+			<jdk>1.6</jdk>

+		</activation>

+		<modules>

+			<module>hello.impl.annotation</module>

+			<module>hello.client.annotation</module>

+		</modules>

+	</profile>

+  </profiles>

+</project>
\ No newline at end of file
diff --git a/ipojo/extender.pattern.handler/metadata.xml b/ipojo/extender.pattern.handler/metadata.xml
new file mode 100644
index 0000000..cb45ffc
--- /dev/null
+++ b/ipojo/extender.pattern.handler/metadata.xml
@@ -0,0 +1,6 @@
+<ipojo>

+	<handler

+		classname="org.apache.felix.ipojo.handler.extender.ExtenderModelHandler"

+		name="extender" namespace="org.apache.felix.ipojo.extender">

+	</handler>

+</ipojo>
\ No newline at end of file
diff --git a/ipojo/extender.pattern.handler/pom.xml b/ipojo/extender.pattern.handler/pom.xml
new file mode 100644
index 0000000..a89fbd0
--- /dev/null
+++ b/ipojo/extender.pattern.handler/pom.xml
@@ -0,0 +1,91 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO Extender Pattern Handler</name>

+	<artifactId>

+		org.apache.felix.ipojo.handler.extender.pattern

+	</artifactId>

+

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.compendium</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Private-Package>

+							org.apache.felix.ipojo.handler.extender

+						</Private-Package>

+						<Bundle-Name>${pom.name}</Bundle-Name>

+						<Bundle-SymbolicName>

+							org.apache.felix.ipojo.handler.extender.pattern

+						</Bundle-SymbolicName>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<metadata>metadata.xml</metadata>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderManager.java b/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderManager.java
new file mode 100644
index 0000000..aa8341a
--- /dev/null
+++ b/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderManager.java
@@ -0,0 +1,178 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.extender;

+

+import java.lang.reflect.InvocationTargetException;

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.util.Callback;

+import org.osgi.framework.Bundle;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.BundleEvent;

+import org.osgi.framework.SynchronousBundleListener;

+

+/**

+ * Track and manage extensions.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ExtenderManager implements SynchronousBundleListener {

+    

+    /**

+     * Looked extension.

+     */

+    private String m_extension;

+    

+    /**

+     * OnArrival method. 

+     */

+    private Callback m_onArrival;

+    

+    /**

+     * OnDeparture method. 

+     */

+    private Callback m_onDeparture;

+    

+    /**

+     * Attached handler. 

+     */

+    private PrimitiveHandler m_handler;

+    

+    /**

+     * Bundle context. 

+     */

+    private BundleContext m_context;

+    

+    /**

+     * List of managed bundles. 

+     */

+    private List m_bundles = new ArrayList();

+    

+    /**

+     * Constructor.

+     * @param handler : attached handler.

+     * @param extension : looked extension.

+     * @param bind : onArrival method

+     * @param unbind : onDeparture method.

+     */

+    public ExtenderManager(ExtenderModelHandler handler, String extension, String bind, String unbind) {

+        m_handler = handler;

+        m_onArrival = new Callback(bind, new Class[] {Bundle.class, String.class}, false, m_handler.getInstanceManager());

+        m_onDeparture = new Callback(unbind, new Class[] {Bundle.class}, false, m_handler.getInstanceManager());

+        m_extension = extension;

+        m_context = handler.getInstanceManager().getContext();

+    }

+    

+    /**

+     * Start method.

+     * Look for already presents bundle and register a (synchronous) bundle listener.

+     */

+    public void start() {

+        synchronized (this) {

+            // listen to any changes in bundles.

+            m_context.addBundleListener(this);

+            // compute already started bundles.

+            for (int i = 0; i < m_context.getBundles().length; i++) {

+                if (m_context.getBundles()[i].getState() == Bundle.ACTIVE) {

+                    onArrival(m_context.getBundles()[i]);

+                }

+            }

+        }

+    }

+    

+    /**

+     * Manage a bundle arrival:

+     * Check the extension and manage it if present.

+     * @param bundle : bundle.

+     */

+    private void onArrival(Bundle bundle) {

+        Dictionary headers = bundle.getHeaders();

+        String header = (String) headers.get(m_extension);

+        if (header != null) {

+            m_bundles.add(bundle);

+            try {

+                m_onArrival.call(new Object[] {bundle, header});

+            } catch (NoSuchMethodException e) {

+                m_handler.error("The onArrival method " + m_onArrival.getMethod() + " does not exist in the class", e);

+                m_handler.getInstanceManager().stop();

+            } catch (IllegalAccessException e) {

+                m_handler.error("The onArrival method " + m_onArrival.getMethod() + " cannot be called", e);

+                m_handler.getInstanceManager().stop();

+            } catch (InvocationTargetException e) {

+                m_handler.error("The onArrival method " + m_onArrival.getMethod() + " has thrown an exception", e.getTargetException());

+                m_handler.getInstanceManager().stop();

+            }

+        }

+    }

+

+    /**

+     * Stop method.

+     * Remove the bundle listener. 

+     */

+    public void stop() {

+        m_context.removeBundleListener(this);

+        m_bundles.clear();

+    }

+

+    /**

+     * Bundle listener.

+     * @param event : event.

+     * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)

+     */

+    public void bundleChanged(BundleEvent event) {

+        switch (event.getType()) {

+            case BundleEvent.STARTED:

+                onArrival(event.getBundle());

+                break;

+            case BundleEvent.STOPPING:

+                onDeparture(event.getBundle());

+                break;

+            default: 

+                break;

+        }

+        

+    }

+

+    /**

+     * Manage a bundle departure.

+     * If the bundle was managed, invoke the OnDeparture callback, and remove the bundle from the list.

+     * @param bundle : bundle.

+     */

+    private void onDeparture(Bundle bundle) {

+        if (m_bundles.contains(bundle)) {

+            try {

+                m_onDeparture.call(new Object[] {bundle});

+            } catch (NoSuchMethodException e) {

+                m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " does not exist in the class", e);

+                m_handler.getInstanceManager().stop();

+            } catch (IllegalAccessException e) {

+                m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " cannot be called", e);

+                m_handler.getInstanceManager().stop();

+            } catch (InvocationTargetException e) {

+                m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " has thrown an exception", e.getTargetException());

+                m_handler.getInstanceManager().stop();

+            }

+        }

+    }

+

+    

+

+}

diff --git a/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderModelHandler.java b/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderModelHandler.java
new file mode 100644
index 0000000..8fc50b9
--- /dev/null
+++ b/ipojo/extender.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/extender/ExtenderModelHandler.java
@@ -0,0 +1,94 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.extender;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.metadata.Element;

+

+/**

+ * Handler automating extender pattern. The component using this handler is notified 

+ * when an handler with a special manifest extension is detected, the component is notified.

+ * When a managed handler leaves, the component is also notified.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class ExtenderModelHandler extends PrimitiveHandler {

+    

+    /**

+     * Handler namespace.

+     */

+    public static final String NAMESPACE = "org.apache.felix.ipojo.extender";

+    

+    /**

+     * Extension manager list.

+     */

+    private List m_managers = new ArrayList(1);

+

+    /**

+     * Configure method.

+     * @param elem : component type element.

+     * @param dict : instance configuration.

+     * @throws ConfigurationException : the configuration is not valid.

+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

+    public void configure(Element elem, Dictionary dict) throws ConfigurationException {

+        Element[] elems = elem.getElements("extender", NAMESPACE);

+        for (int i = 0; i < elems.length; i++) {

+            String extension = elems[i].getAttribute("extension");

+            String onArrival = elems[i].getAttribute("onArrival");

+            String onDeparture = elems[i].getAttribute("onDeparture");

+            

+            if (extension == null) {

+                throw new ConfigurationException("The extender element requires an 'extender' attribute");

+            }

+            if (onArrival == null || onDeparture == null) {

+                throw new ConfigurationException("The extender element requires the onArrival and onDeparture attributes");

+            }

+            

+            ExtenderManager wbm = new ExtenderManager(this, extension, onArrival, onDeparture);

+            m_managers.add(wbm);

+        }

+        

+    }

+

+    /**

+     * Start the handler.

+     * @see org.apache.felix.ipojo.Handler#start()

+     */

+    public void start() {

+        for (int i = 0; i < m_managers.size(); i++) {

+            ((ExtenderManager) m_managers.get(i)).start();

+        }

+    }

+

+    /**

+     * Stop the handler.

+     * @see org.apache.felix.ipojo.Handler#stop()

+     */

+    public void stop() {

+        for (int i = 0; i < m_managers.size(); i++) {

+            ((ExtenderManager) m_managers.get(i)).stop();

+        } 

+    }

+

+}

diff --git a/ipojo/jmx.handler/pom.xml b/ipojo/jmx.handler/pom.xml
index fb5750c..f2da02d 100644
--- a/ipojo/jmx.handler/pom.xml
+++ b/ipojo/jmx.handler/pom.xml
@@ -1,49 +1,53 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

 <project>

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

 	<modelVersion>4.0.0</modelVersion>

 	<packaging>bundle</packaging>

-	<groupId>org.apache.felix</groupId>

 	<artifactId>org.apache.felix.ipojo.handler.jmx</artifactId>

-	<version>0.7.5-SNAPSHOT</version>

-	<name>iPOJO JMX Handler</name>

+	<name>Apache Felix iPOJO JMX Handler</name>

 

 	<dependencies>

 		<dependency>

 			<groupId>org.apache.felix</groupId>

 			<artifactId>org.osgi.core</artifactId>

-			<version>1.1.0-SNAPSHOT</version>

+			<version>1.0.0</version>

 		</dependency>

 		<dependency>

 			<groupId>org.apache.felix</groupId>

 			<artifactId>org.osgi.compendium</artifactId>

-            <version>1.0.0</version>
+			<version>1.0.0</version>

 		</dependency>

 		<dependency>

 			<groupId>org.apache.felix</groupId>

 			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

-			<version>0.7.5-SNAPSHOT</version>

+			<version>${pom.version}</version>

 		</dependency>

 		<dependency>

 			<groupId>org.apache.felix</groupId>

 			<artifactId>org.apache.felix.ipojo</artifactId>

-			<version>0.7.5-SNAPSHOT</version>

+			<version>${pom.version}</version>

 		</dependency>

 	</dependencies>

 

@@ -52,7 +56,7 @@
 			<plugin>

 				<groupId>org.apache.felix</groupId>

 				<artifactId>maven-bundle-plugin</artifactId>

-                <version>1.4.0</version>
+				<version>1.4.0</version>

 				<extensions>true</extensions>

 				<configuration>

 					<instructions>

@@ -60,7 +64,9 @@
 							org.apache.felix.ipojo.handlers.jmx

 						</Private-Package>

 						<Bundle-Name>${pom.name}</Bundle-Name>

-						<Bundle-SymbolicName>ipojo.jmx.handler</Bundle-SymbolicName>

+						<Bundle-SymbolicName>

+							ipojo.jmx.handler

+						</Bundle-SymbolicName>

 					</instructions>

 				</configuration>

 			</plugin>

@@ -73,20 +79,20 @@
 				</configuration>

 			</plugin>

 			<plugin>

-		      <groupId>org.apache.felix</groupId>

-		      <artifactId>maven-ipojo-plugin</artifactId>

-	          	<version>${pom.version}</version>

-		  		<executions>

-	      			<execution>

-	        			<goals>

-	              			<goal>ipojo-bundle</goal>

-	           			</goals>

-	        			<configuration>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

 							<metadata>metadata.xml</metadata>

-	        			</configuration>

-	      			</execution>

-	    		</executions>

-      		</plugin>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

 		</plugins>

 	</build>

 </project>

diff --git a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java
index 0c36ab0..c539f82 100644
--- a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java
+++ b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java
@@ -43,6 +43,7 @@
 import org.apache.felix.ipojo.InstanceManager;

 import org.apache.felix.ipojo.parser.MethodMetadata;

 import org.apache.felix.ipojo.util.Callback;

+import org.apache.felix.ipojo.util.Logger;

 

 /** 

  * this class implements iPOJO DynamicMBean.

@@ -55,24 +56,27 @@
      * JmxConfigDFieldMap : store the data extracted from metadata.xml.

      */

     private JmxConfigFieldMap m_configMap;

+

     /** 

      * InstanceManager: use to store the InstanceManager instance.

      */

     private InstanceManager m_instanceManager;

+

     /** 

      * MBeanInfo : class wich store the MBean Informations.

      */

     private MBeanInfo m_mBeanInfo;

+

     /**

      * String : constant which store the name of the class.

      */

     private String m_className = this.getClass().getName();

-    

+

     /** 

      * sequenceNumber : use to calculate unique id to notification.

      */

     private int m_sequenceNumber = 0;

-    

+

     /** 

      * DynamicMBeanImpl : constructor.

      * @param properties : data extracted from metadat.xml file

@@ -83,7 +87,7 @@
         m_instanceManager = instanceManager;

         this.buildMBeanInfo();

     }

-    

+

     /** 

      * getAttribute implements from JMX.

      * get the value of the required attribute 

@@ -95,13 +99,14 @@
      */

     public Object getAttribute(String arg0) throws AttributeNotFoundException, MBeanException, ReflectionException {

         PropertyField attribute = m_configMap.getPropertyFromName(arg0);

-        

+

         if (attribute == null) {

             throw new AttributeNotFoundException(arg0 + " not found");

         } else {

             return attribute.getValue();

         }

     }

+

     /** 

      * getAttributes : implement from JMX.

      * get values of reuqired attributes 

@@ -109,21 +114,22 @@
      * @return return the list of the attribute

      */

     public AttributeList getAttributes(String[] attributeNames) {

-        

+

         if (attributeNames == null) {

             throw new IllegalArgumentException("attributeNames[] cannot be null");

         }

-        

+

         AttributeList resultList = new AttributeList();

         for (int i = 0; i < attributeNames.length; i++) {

             PropertyField propertyField = (PropertyField) m_configMap.getPropertyFromField((String) attributeNames[i]);

-            

+

             if (propertyField != null) {

                 resultList.add(new Attribute(attributeNames[i], propertyField.getValue()));

             }

         }

         return resultList;

     }

+

     /** 

      * getMBeanInfo : return the MBean Class builded.

      * @return  return MBeanInfo class constructed by buildMBeanInfo

@@ -131,6 +137,7 @@
     public MBeanInfo getMBeanInfo() {

         return m_mBeanInfo;

     }

+

     /** 

      * invoke : invoke the required method on the targeted POJO.

      * @param operationName : name of the method called

@@ -159,13 +166,15 @@
                 e.printStackTrace();

             }

         } else {

-            throw new ReflectionException(new NoSuchMethodException(

-                    operationName), "Cannot find the operation "

-                    + operationName + " in " + m_className);

+            throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation "

+                    + operationName

+                    + " in "

+                    + m_className);

         }

-        

+

         return null;

     }

+

     /** 

      * setAttribute : change specified attribute value.

      * @param attribute : attribute with new value to be changed

@@ -174,71 +183,68 @@
      * @throws MBeanException :

      * @throws ReflectionException :

      */

-    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {

-        

+    public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException,

+            ReflectionException {

+

         // Check attribute is not null to avoid NullPointerException later on

         if (attribute == null) {

-            throw new RuntimeOperationsException(new IllegalArgumentException(

-                    "Attribute cannot be null"), "Cannot invoke a setter of "

-                    + m_className + " with null attribute");

+            throw new RuntimeOperationsException(new IllegalArgumentException("Attribute cannot be null"), "Cannot invoke a setter of "

+                    + m_className

+                    + " with null attribute");

         }

         String name = attribute.getName();

         Object value = attribute.getValue();

 

         if (name == null) {

-            throw new RuntimeOperationsException(new IllegalArgumentException(

-                    "Attribute name cannot be null"),

-                    "Cannot invoke the setter of " + m_className

-                            + " with null attribute name");

+            throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name cannot be null"), "Cannot invoke the setter of "

+                    + m_className

+                    + " with null attribute name");

         }

         // Check for a recognized attribute name and call the corresponding

         // setter

         //

-        

+

         PropertyField propertyField = (PropertyField) m_configMap.getPropertyFromName(name);

         if (propertyField == null) {

             // unrecognized attribute name:

-            throw new AttributeNotFoundException("Attribute " + name

-                    + " not found in " + m_className);

+            throw new AttributeNotFoundException("Attribute " + name + " not found in " + m_className);

         }

         if (!propertyField.isWritable()) {

-            throw new InvalidAttributeValueException(

-                    "Attribute " + name + " can not be setted");

+            throw new InvalidAttributeValueException("Attribute " + name + " can not be setted");

         }

-        

+

         if (value == null) {

             try {

-                m_instanceManager.setterCallback(propertyField.getField(), null);

+                m_instanceManager.onSet(null, propertyField.getField(), null);

             } catch (Exception e) {

-                throw new InvalidAttributeValueException(

-                        "Cannot set attribute " + name + " to null");

+                throw new InvalidAttributeValueException("Cannot set attribute " + name + " to null");

             }

         } else { // if non null value, make sure it is assignable to the attribute

             if (true /* TODO type.class.isAssignableFrom(value.getClass())*/) {

                 //propertyField.setValue(value);

                 // setValue(attributeField.getField(),null);

-                m_instanceManager.setterCallback(propertyField.getField(), value);

+                m_instanceManager.onSet(null, propertyField.getField(), value);

             } else {

-                throw new InvalidAttributeValueException(

-                        "Cannot set attribute " + name + " to a "

-                                + value.getClass().getName()

-                                + " object, String expected");

+                throw new InvalidAttributeValueException("Cannot set attribute "

+                        + name

+                        + " to a "

+                        + value.getClass().getName()

+                        + " object, String expected");

             }

         }

 

-        

     }

+

     /** 

      * setAttributes : change all the attributes value.

      * @param attributes : list of attribute value to be changed

      * @return AttributeList : list of new attribute

      */

     public AttributeList setAttributes(AttributeList attributes) {

-        

-//       Check attributes is not null to avoid NullPointerException later on

+

+        //       Check attributes is not null to avoid NullPointerException later on

         if (attributes == null) {

-            throw new RuntimeOperationsException(new IllegalArgumentException(

-                    "AttributeList attributes cannot be null"),

+            throw new RuntimeOperationsException(new IllegalArgumentException("AttributeList attributes cannot be null"),

                     "Cannot invoke a setter of " + m_className);

         }

         AttributeList resultList = new AttributeList();

@@ -247,7 +253,7 @@
         if (attributes.isEmpty()) {

             return resultList;

         }

-        

+

         // for each attribute, try to set it and add to the result list if

         // successfull

         for (Iterator i = attributes.iterator(); i.hasNext();) {

@@ -263,58 +269,45 @@
         }

         return resultList;

     }

+

     /** 

-     * buildMBeanInfo : buil the MBean information on initilisation.

+     * buildMBeanInfo : build the MBean information on initialization.

      * this value don't change after

      */

     private void buildMBeanInfo() {

         String dDescription = m_configMap.getDecription();

-        

+

         // generate infos for attributes

         MBeanAttributeInfo[] dAttributes = null;

-        

+

         if (m_configMap == null) {

             return;

         }

-        

-        if (m_configMap.getProperties() != null) {

-            List <MBeanAttributeInfo> lAttributes = null;            

-            lAttributes = new ArrayList <MBeanAttributeInfo> ();

 

-            Iterator <PropertyField> iterator = m_configMap.getProperties().iterator();

+        if (m_configMap.getProperties() != null) {

+            List<MBeanAttributeInfo> lAttributes = null;

+            lAttributes = new ArrayList<MBeanAttributeInfo>();

+

+            Iterator<PropertyField> iterator = m_configMap.getProperties().iterator();

             while (iterator.hasNext()) {

                 PropertyField propertyField = (PropertyField) iterator.next();

-                lAttributes.add(new MBeanAttributeInfo(

-                        propertyField.getName(),

-                        propertyField.getType(),

-                        propertyField.getDescription(),

-                        propertyField.isReadable(),

-                        propertyField.isWritable(),

-                        false));                

+                lAttributes.add(new MBeanAttributeInfo(propertyField.getName(), propertyField.getType(), propertyField.getDescription(),

+                        propertyField.isReadable(), propertyField.isWritable(), false));

             }

-            dAttributes = (MBeanAttributeInfo[]) lAttributes.toArray(new MBeanAttributeInfo[ lAttributes.size() ]);

+            dAttributes = (MBeanAttributeInfo[]) lAttributes.toArray(new MBeanAttributeInfo[lAttributes.size()]);

         }

 

-

-        

         MBeanOperationInfo[] dOperations = null;

         if (m_configMap.getMethods() != null) {

-            

-            List <MBeanOperationInfo> lOperations = new ArrayList <MBeanOperationInfo>();

-            

-            Iterator <MethodField[]> iterator = m_configMap.getMethods().iterator();

+

+            List<MBeanOperationInfo> lOperations = new ArrayList<MBeanOperationInfo>();

+

+            Iterator<MethodField[]> iterator = m_configMap.getMethods().iterator();

             while (iterator.hasNext()) {

                 MethodField[] method = (MethodField[]) iterator.next();

-                for (int i = 0 ; i < method.length ; i++) {

-                    lOperations.add(

-                            new MBeanOperationInfo(

-                                    method[i].getName(),

-                                    method[i].getDescription(),

-                                    method[i].getParams(),

-                                    method[i].getReturnType(),

-                                    MBeanOperationInfo.UNKNOWN

-                        )

-                    );

+                for (int i = 0; i < method.length; i++) {

+                    lOperations.add(new MBeanOperationInfo(method[i].getName(), method[i].getDescription(), method[i].getParams(), method[i]

+                            .getReturnType(), MBeanOperationInfo.UNKNOWN));

                 }

                 dOperations = (MBeanOperationInfo[]) lOperations.toArray(new MBeanOperationInfo[lOperations.size()]);

             }

@@ -322,10 +315,10 @@
 

         MBeanNotificationInfo[] dNotification = new MBeanNotificationInfo[0];

         if (m_configMap.getMethods() != null) {

-                

-            List <MBeanNotificationInfo> lNotifications = new ArrayList <MBeanNotificationInfo>();

-                

-            Iterator <NotificationField> iterator = m_configMap.getNotifications().iterator();

+

+            List<MBeanNotificationInfo> lNotifications = new ArrayList<MBeanNotificationInfo>();

+

+            Iterator<NotificationField> iterator = m_configMap.getNotifications().iterator();

             while (iterator.hasNext()) {

                 NotificationField notification = (NotificationField) iterator.next();

                 lNotifications.add(notification.getNotificationInfo());

@@ -333,13 +326,8 @@
             dNotification = (MBeanNotificationInfo[]) lNotifications.toArray(new MBeanNotificationInfo[lNotifications.size()]);

         }

 

-        m_mBeanInfo = new MBeanInfo(

-                this.m_className,

-                dDescription,

-                dAttributes,

-                null, // No constructor 

-                dOperations,

-                dNotification);

+        m_mBeanInfo = new MBeanInfo(this.m_className, dDescription, dAttributes, null, // No constructor 

+                dOperations, dNotification);

     }

 

     /** 

@@ -349,10 +337,10 @@
     public MBeanNotificationInfo[] getNotificationInfo() {

         MBeanNotificationInfo[] dNotification = new MBeanNotificationInfo[0];

         if (m_configMap.getMethods() != null) {

-                

-            List < MBeanNotificationInfo> lNotifications = new ArrayList < MBeanNotificationInfo>();

-                

-            Iterator <NotificationField> iterator = m_configMap.getNotifications().iterator();

+

+            List<MBeanNotificationInfo> lNotifications = new ArrayList<MBeanNotificationInfo>();

+

+            Iterator<NotificationField> iterator = m_configMap.getNotifications().iterator();

             while (iterator.hasNext()) {

                 NotificationField notification = (NotificationField) iterator.next();

                 lNotifications.add(notification.getNotificationInfo());

@@ -361,7 +349,7 @@
         }

         return dNotification;

     }

- 

+

     /** 

      * sendNotification : send a notification to a subscriver.

      * @param msg : msg to send

@@ -370,20 +358,17 @@
      * @param oldValue : oldvalue of the attribute

      * @param newValue : new value of the attribute

      */

-    public void sendNotification(String msg, String attributeName,

-            String attributeType, Object oldValue, Object newValue) {

+    public void sendNotification(String msg, String attributeName, String attributeType, Object oldValue, Object newValue) {

 

         long timeStamp = System.currentTimeMillis();

-        

-               

+

         if (newValue.equals(oldValue)) {

             return;

         }

         m_sequenceNumber++;

-        Notification notification = new AttributeChangeNotification(

-                this, m_sequenceNumber, timeStamp,

-                msg, attributeName, attributeType, oldValue, newValue);

+        Notification notification =

+                new AttributeChangeNotification(this, m_sequenceNumber, timeStamp, msg, attributeName, attributeType, oldValue, newValue);

         sendNotification(notification);

-        System.out.println("DEBUG: Notification sent");

+        m_instanceManager.getFactory().getLogger().log(Logger.INFO, "Notification sent");

     }

 }

diff --git a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/JmxConfigFieldMap.java b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/JmxConfigFieldMap.java
index 64a72da..c3df29d 100644
--- a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/JmxConfigFieldMap.java
+++ b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/JmxConfigFieldMap.java
@@ -228,7 +228,6 @@
             return false;

         } else {

             for (int i = 0; i < sig1.length; i++) {

-                //System.out.println(sig1[i] +" == "+ sig2[i]);

                 if (!sig1[i].equals(sig2[i])) {

                     return false;

                 }

diff --git a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java
index 9e04bb0..ff3dd17 100644
--- a/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java
+++ b/ipojo/jmx.handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java
@@ -27,12 +27,13 @@
 import org.apache.felix.ipojo.PrimitiveHandler;

 import org.apache.felix.ipojo.metadata.Element;

 import org.apache.felix.ipojo.parser.FieldMetadata;

-import org.apache.felix.ipojo.parser.ManipulationMetadata;

 import org.apache.felix.ipojo.parser.MethodMetadata;

+import org.apache.felix.ipojo.parser.PojoMetadata;

 import org.osgi.framework.BundleContext;

 import org.osgi.framework.ServiceRegistration;

 

-/** this class implements iPOJO Handler.

+/** 

+ * This class implements iPOJO Handler.

  * it builds the dynamic MBean from metadata.xml and expose it to the MBean Server.

  *  

  *  @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

@@ -43,7 +44,7 @@
      */

     private InstanceManager m_instanceManager;

     /**

-     * ServiceRegistration : use to register and deregister the Dynamic MBean.

+     * ServiceRegistration : use to register and unregister the Dynamic MBean.

      */

     private ServiceRegistration m_serviceRegistration;

     /**

@@ -57,16 +58,16 @@
     /**

      * String : constant which store the name of the class.

      */

-    private String m_NAMESPACE = this.getClass().getName();

+    private String m_namespace = this.getClass().getName();

 

     /** 

      * configure : construct the structure JmxConfigFieldMap.and the Dynamic Mbean.

      * @param metadata Element

-     * @param dict Dictionnary

+     * @param dict Dictionary

      */

     public void configure(Element metadata, Dictionary dict) {

         

-        ManipulationMetadata manipulation = new ManipulationMetadata(metadata);

+        PojoMetadata manipulation = getPojoMetadata();

         

         m_instanceManager = getInstanceManager();

 

@@ -74,7 +75,7 @@
         m_jmxConfigFieldMap = new JmxConfigFieldMap();

 

         // Build the hashmap

-        Element[] mbeans = metadata.getElements("config", m_NAMESPACE);

+        Element[] mbeans = metadata.getElements("config", m_namespace);

 

         if (mbeans.length != 1) { return; }

         

@@ -83,47 +84,48 @@
         // set property 

         Element[] attributes = mbeans[0].getElements("property");

         //String[] fields = new String[attributes.length];

-        FieldMetadata[] fields = new FieldMetadata[attributes.length];

-        for (int i = 0 ; i < attributes.length ; i++) {

-            boolean notif = false;

-            String rights;

-            String name;

-            String field = attributes[i].getAttribute("field");

+        if (attributes != null) {

+            for (int i = 0 ; attributes != null && i < attributes.length ; i++) {

+                boolean notif = false;

+                String rights;

+                String name;

+                String field = attributes[i].getAttribute("field");

             

-            if (attributes[i].containsAttribute("name")) {

-                name = attributes[i].getAttribute("name");

-            } else {

-                name = field;

-            }

-            if (attributes[i].containsAttribute("rights")) {

-                rights = attributes[i].getAttribute("rights");

-            } else {

-                rights = "w";

-            }

+                if (attributes[i].containsAttribute("name")) {

+                    name = attributes[i].getAttribute("name");

+                } else {

+                    name = field;

+                }

+                if (attributes[i].containsAttribute("rights")) {

+                    rights = attributes[i].getAttribute("rights");

+                } else {

+                    rights = "w";

+                }

             

-            PropertyField property = new PropertyField(name, field, rights, getTypeFromAttributeField(field, manipulation));

+                PropertyField property = new PropertyField(name, field, rights, getTypeFromAttributeField(field, manipulation));

             

-            if (attributes[i].containsAttribute("notification")) {

-                notif = Boolean.parseBoolean(attributes[i].getAttribute("notification"));

-            }

+                if (attributes[i].containsAttribute("notification")) {

+                    notif = Boolean.parseBoolean(attributes[i].getAttribute("notification"));

+                }

             

-            property.setNotifiable(notif);

+                property.setNotifiable(notif);

             

-            if (notif) {

-                //add the new notifiable property in structure

-                NotificationField notification = new NotificationField(name, this.getClass().getName() + "." + field, null);

-                m_jmxConfigFieldMap.addNotificationFromName(name, notification);

-            }

-            m_jmxConfigFieldMap.addPropertyFromName(name, property);

-            fields[i] = manipulation.getField(field);

-            System.out.println("DEBUG: property exposed:" + name + " " + field + ":" 

+                if (notif) {

+                    //add the new notifiable property in structure

+                    NotificationField notification = new NotificationField(name, this.getClass().getName() + "." + field, null);

+                    m_jmxConfigFieldMap.addNotificationFromName(name, notification);

+                }

+                m_jmxConfigFieldMap.addPropertyFromName(name, property);

+                getInstanceManager().register(manipulation.getField(field), this);

+                info("property exposed:" + name + " " + field + ":" 

                     + getTypeFromAttributeField(field, manipulation) + " " + rights 

                     + ", Notif=" + notif);

+            }

         }

         

         //set methods 

         Element[] methods = mbeans[0].getElements("method");

-        for (int i = 0 ; i < methods.length ; i++) {

+        for (int i = 0 ; methods != null && i < methods.length ; i++) {

             String name = methods[i].getAttribute("name");

             String description = null;

             if (methods[i].containsAttribute("description")) {

@@ -135,19 +137,16 @@
             for (int j = 0 ; j < method.length ; j++) {

                 m_jmxConfigFieldMap.addMethodFromName(name, method[j]);

             

-                System.out.println("DEBUG: method exposed:" + method[j].getReturnType() + " " + name);

+                info("method exposed:" + method[j].getReturnType() + " " + name);

             }

         }

-

-        m_instanceManager.register(this, fields, null);

         

     }

     /**

      * start : register the Dynamic Mbean.

      */

     public void start() {

-        

-//      create the corresponding MBean

+        // create the corresponding MBean

         m_MBean = new DynamicMBeanImpl(m_jmxConfigFieldMap, m_instanceManager);

         if (m_serviceRegistration != null) { m_serviceRegistration.unregister(); }

 

@@ -163,21 +162,20 @@
     }

 

     /** 

-     * stop : deregister the Dynamic Mbean.

+     * stop : unregister the Dynamic Mbean.

      */

     public void stop() {

         if (m_serviceRegistration != null) { m_serviceRegistration.unregister(); }

-        

-        

     }

     

     

     /** 

      * setterCallback : call when a POJO member is modified externally.

+     * @param pojo : the POJO object

      * @param fieldName : name of the modified field 

      * @param value     : new value of the field

      */

-    public void setterCallback(String fieldName, Object value) {

+    public void onSet(Object pojo, String fieldName, Object value) {

         // Check if the field is a configurable property

 

         PropertyField propertyField = (PropertyField) m_jmxConfigFieldMap.getPropertyFromField(fieldName);

@@ -193,20 +191,20 @@
 

     /** 

      * getterCallback : call when a POJO member is modified by the MBean.

+     * @pojo : pojo object.

      * @param fieldName : name of the modified field 

      * @param value     : old value of the field

      * @return          : new value of the field

      */

-    public Object getterCallback(String fieldName, Object value) {

-        

+    public Object onGet(Object pojo, String fieldName, Object value) {

         

         // Check if the field is a configurable property

         PropertyField propertyField = (PropertyField) m_jmxConfigFieldMap.getPropertyFromField(fieldName);

         if (propertyField != null) { 

-            m_instanceManager.setterCallback(fieldName, propertyField.getValue());

+            m_instanceManager.onSet(pojo, fieldName, propertyField.getValue());

             return propertyField.getValue();

         }

-        m_instanceManager.setterCallback(fieldName, value);

+        m_instanceManager.onSet(pojo, fieldName, value);

         return value;

     }

     

@@ -216,13 +214,13 @@
      * @param manipulation : metadata extract from metadata.xml file

      * @return          : type of the field or null if it wasn't found

      */

-    private static String getTypeFromAttributeField(String fieldRequire, ManipulationMetadata manipulation) {

+    private static String getTypeFromAttributeField(String fieldRequire, PojoMetadata manipulation) {

         

         FieldMetadata field = manipulation.getField(fieldRequire);

         if (field == null) {

             return null;

         } else {

-            return field.getReflectionType();

+            return FieldMetadata.getReflectionType(field.getFieldType());

         }

     }

     

@@ -233,7 +231,7 @@
      * @param description  : description which appears in jmx console

      * @return          : array of methods with the right name

      */

-    private MethodField[] getMethodsFromName(String methodName, ManipulationMetadata manipulation, String description) {

+    private MethodField[] getMethodsFromName(String methodName, PojoMetadata manipulation, String description) {

         

         MethodMetadata[] fields = manipulation.getMethods(methodName);

         if (fields.length == 0) {

diff --git a/ipojo/manipulator/pom.xml b/ipojo/manipulator/pom.xml
index 45e50dd..afa5a94 100644
--- a/ipojo/manipulator/pom.xml
+++ b/ipojo/manipulator/pom.xml
@@ -1,82 +1,79 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix</artifactId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-  <version>0.7.5-SNAPSHOT</version>
-  <name>Apache Felix iPOJO Manipulator</name>

-  

-  
-  <dependencies>
-    <dependency>
-      <groupId>asm</groupId>
-      <artifactId>asm</artifactId>
-      <version>3.0</version>
-    </dependency>
-    <dependency>
-      <groupId>asm</groupId>
-      <artifactId>asm-commons</artifactId>
-      <version>3.0</version>

-      <exclusions>

-    	<exclusion>

-      		<groupId>asm</groupId>

-      		<artifactId>asm-tree</artifactId>

-    	</exclusion>

-  	   </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.0</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>          
-            <Bundle-Name>iPOJO Manipulator</Bundle-Name>
-            <Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
-            <Bundle-Description> iPOJO Manipulator </Bundle-Description>
-            <Export-Package>org.apache.felix.ipojo.manipulator</Export-Package>
-            <Private-Package>
-            	org.apache.felix.ipojo.manipulation,
-            	org.apache.felix.ipojo.manipulation.annotations,
-            	org.apache.felix.ipojo.xml.parser,
-              	org.objectweb.asm,
-              	org.objectweb.asm.commons
-            </Private-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<artifactId>org.apache.felix.ipojo.manipulator</artifactId>

+	<name>Apache Felix iPOJO Manipulator</name>

+

+	<dependencies>

+		<dependency>

+			<groupId>asm</groupId>

+			<artifactId>asm-all</artifactId>

+			<version>3.0</version>

+			<exclusions>

+				<exclusion>

+					<groupId>asm</groupId>

+					<artifactId>asm-tree</artifactId>

+				</exclusion>

+			</exclusions>

+		</dependency>

+		<dependency>

+			<groupId>${pom.groupId}</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-Name>iPOJO Manipulator</Bundle-Name>

+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>

+						<Bundle-Description>

+							iPOJO Manipulator

+						</Bundle-Description>

+						<Export-Package>

+							org.apache.felix.ipojo.manipulator

+						</Export-Package>

+						<Private-Package>

+							org.apache.felix.ipojo.manipulation,

+							org.apache.felix.ipojo.manipulation.annotations,

+							org.apache.felix.ipojo.xml.parser,

+							org.objectweb.asm, org.objectweb.asm.commons

+						</Private-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
index b026c17..658f18a 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
@@ -76,12 +76,14 @@
     public FieldVisitor visitField(int access, String name, String desc,

             String signature, Object value) {

 

-        if (access == ACC_PRIVATE && name.equals("_cm")

+        if (access == ACC_PRIVATE && name.equals(MethodCreator.IM_FIELD)

                 && desc.equals("Lorg/apache/felix/ipojo/InstanceManager;")) {

             m_isAlreadyManipulated = true;

         } else if (name.startsWith("class$")) { // Does not add class$* field generated by 'x.class'

             return null;

-        } 

+        } else if ((access & ACC_STATIC) == ACC_STATIC) {

+            return null;

+        }

         

         Type type = Type.getType(desc);

         if (type.getSort() == Type.ARRAY) {

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
index e552072..2902b74 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ConstructorCodeAdapter.java
@@ -23,7 +23,6 @@
 import org.objectweb.asm.Label;

 import org.objectweb.asm.MethodVisitor;

 import org.objectweb.asm.Opcodes;

-import org.objectweb.asm.Type;

 import org.objectweb.asm.commons.GeneratorAdapter;

 

 

@@ -48,11 +47,6 @@
      * Set of contained fields.

      */

     private Set m_fields;

-    

-    /**

-     * Constructor description.

-     */

-    private String m_desc;

 

     /** 

      * PropertyCodeAdapter constructor.

@@ -69,7 +63,6 @@
         m_owner = owner;

         m_superDetected = false;

         m_fields = fields;

-        m_desc = desc;

     }

 

 

@@ -89,12 +82,12 @@
         if (m_fields.contains(name) && m_owner.equals(owner)) {

             if (opcode == GETFIELD) {

                 String gDesc = "()" + desc;

-                visitMethodInsn(INVOKESPECIAL, owner, "_get" + name, gDesc);

+                visitMethodInsn(INVOKESPECIAL, owner, "__get" + name, gDesc);

                 return;

             } else

                 if (opcode == PUTFIELD) {

                     String sDesc = "(" + desc + ")V";

-                    visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);

+                    visitMethodInsn(INVOKESPECIAL, owner, "__set" + name, sDesc);

                     return;

                 }

         }

@@ -124,12 +117,8 @@
             //mv.visitVarInsn(ALOAD, Type.getArgumentTypes(m_constructorDesc).length);

             mv.visitVarInsn(ALOAD, 1);  // CM is always the first argument

             // 3) Initialize the field 

-            mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setComponentManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V");

+            mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setInstanceManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V");

             

-            // Add the entry callback call.

-            methodEntry();

-            

-            // insertion finished   

         } else { 

             mv.visitMethodInsn(opcode, owner, name, desc); 

         }

@@ -197,101 +186,6 @@
     public void visitMaxs(int maxStack, int maxLocals) {

         mv.visitMaxs(maxStack + 1, maxLocals + 2);

     }

-    

-    /**

-     * Visit zero argument instruction.

-     * This allow to catch RETURN instruction in order to insert the invocation to exit callback.

-     * @param opcode : instruction code

-     * @see org.objectweb.asm.MethodAdapter#visitInsn(int)

-     */

-    public void visitInsn(int opcode) {

-        switch(opcode) {

-            case RETURN:

-                onMethodExit(opcode);

-                break;

-            default :

-                break;

-        }

-        super.visitInsn(opcode);

-    }

-    

-    /**

-     * Method injecting call at the entry of each method.

-     */

-    private void methodEntry() {

-        Type[] args = Type.getArgumentTypes(m_desc);

-        String name = "$init";

-        

-        for (int i = 0; i < args.length; i++) {

-            String cn = args[i].getClassName();

-            if (cn.endsWith("[]")) {

-                cn = cn.replace('[', '$');

-                cn = cn.substring(0, cn.length() - 1);

-            }

-            cn = cn.replace('.', '_');

-            name += cn;

-        }

-

-        String flag = "_M" + name;

-

-        Label l0 = new Label();

-        mv.visitLabel(l0);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");

-        Label l1 = new Label();

-        mv.visitJumpInsn(IFEQ, l1);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "entryCallback", "(Ljava/lang/String;)V");

-        mv.visitLabel(l1);

-    }

-

-    /**

-     * Method injecting call at the exit of each method.

-     * @param opcode : returned opcode (ARETURN, IRETURN, ATHROW ...)

-     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodExit(int)

-     */

-    protected void onMethodExit(int opcode) {        

-        Type[] args = Type.getArgumentTypes(m_desc);

-        String name = "$init";

-       

-        for (int i = 0; i < args.length; i++) {

-            String cn = args[i].getClassName();

-            if (cn.endsWith("[]")) {

-                cn = cn.replace('[', '$');

-                cn = cn.substring(0, cn.length() - 1);

-            }

-            cn = cn.replace('.', '_');

-            name += cn;

-        }

-

-        String flag = "_M" + name;

-

-        int local = newLocal(Type.getType(Object.class));

-        local++;

-        visitInsn(ACONST_NULL);

-        

-        mv.visitVarInsn(ASTORE, local);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");

-        Label l5 = new Label();

-        mv.visitJumpInsn(IFEQ, l5);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitVarInsn(ALOAD, local);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "exitCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-        mv.visitLabel(l5);

-    }

-

-

-    /**

-     * Do nothing.

-     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodEnter()

-     */

-    protected void onMethodEnter() { }

 

 }

 

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
deleted file mode 100644
index fec3d3e..0000000
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/FieldAdapter.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.ipojo.manipulation;

-

-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;

-

-/**

- * Create getter and setter for each fields .

- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

- */

-public class FieldAdapter extends ClassAdapter implements Opcodes {

-

-    /**

-     * The owner.

-     * m_owner : String

-     */

-    private String m_owner;

-

-    /**

-     * Constructor.

-     * @param cv : Class visitor

-     */

-    public FieldAdapter(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 : signature of the visited element

-     * @param superName : superclass (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;

-    }

-

-    /**

-     * Visit a Field.

-     * Inject the getter and the setter method for this field.

-     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)

-     * @param access : access 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 : null

-     */

-    public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {

-

-        if ((access & ACC_STATIC) == 0) {

-            //ManipulationProperty.getLogger().log(Level.INFO, "Manipulate the field declaration of " + name);

-            Type type = Type.getType(desc);

-

-            if (type.getSort() == Type.ARRAY) {

-                String gDesc = "()" + desc;

-                createArrayGetter(name, gDesc, type);

-

-                // Generates setter method

-                String sDesc = "(" + desc + ")V";

-                createArraySetter(name, sDesc, type);

-

-            } else {

-                // Generate the getter method

-                String gDesc = "()" + desc;

-                createSimpleGetter(name, gDesc, type);

-

-                // Generates setter method

-                String sDesc = "(" + desc + ")V";

-                createSimpleSetter(name, sDesc, type);

-            }

-

-        }

-

-        return null;

-    }

-

-    /**

-     * Create a getter method for an array.

-     * @param name : field name

-     * @param desc : method description

-     * @param type : contained type (inside the array)

-     */

-    private void createArraySetter(String name, String desc, Type type) {

-        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_set" + name, desc, null, null);

-

-        String internalType = desc.substring(1);

-        internalType = internalType.substring(0, internalType.length() - 2);

-

-        Label l1 = new Label();

-        mv.visitLabel(l1);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-        Label l2 = new Label();

-        mv.visitJumpInsn(IFNE, l2);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitVarInsn(ALOAD, 1);

-        mv.visitFieldInsn(PUTFIELD, m_owner, name, internalType);

-        mv.visitInsn(RETURN);

-        mv.visitLabel(l2);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitVarInsn(ALOAD, 1);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-        mv.visitInsn(RETURN);

-

-        // End

-        mv.visitMaxs(0, 0);

-        mv.visitEnd();

-    }

-

-    /**

-     * Create a setter method for an array.

-     * @param name : field name

-     * @param desc : method description

-     * @param type : contained type (inside the array)

-     */

-    private void createArrayGetter(String name, String desc, Type type) {

-

-        String methodName = "_get" + name;

-        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, methodName, desc, null, null);

-

-        String internalType = desc.substring(2);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-        Label l1 = new Label();

-        mv.visitJumpInsn(IFNE, l1);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);

-        mv.visitInsn(ARETURN);

-        mv.visitLabel(l1);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-        mv.visitTypeInsn(CHECKCAST, internalType);

-        mv.visitInsn(ARETURN);

-

-        // End

-        mv.visitMaxs(0, 0);

-        mv.visitEnd();

-    }

-

-    /**

-     * Create the getter for a field.

-     * @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_PRIVATE, methodName, desc, null, null);

-

-        switch (type.getSort()) {

-            case Type.BOOLEAN:

-            case Type.CHAR:

-            case Type.BYTE:

-            case Type.SHORT:

-            case Type.INT:

-

-                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];

-

-                Label l0 = new Label();

-                mv.visitLabel(l0);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                Label l1 = new Label();

-                mv.visitJumpInsn(IFNE, l1);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

-                mv.visitInsn(IRETURN);

-

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-                mv.visitVarInsn(ASTORE, 1);

-

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitTypeInsn(CHECKCAST, boxingType);

-                mv.visitVarInsn(ASTORE, 2);

-

-                mv.visitVarInsn(ALOAD, 2);

-                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

-                mv.visitInsn(type.getOpcode(IRETURN));

-                break;

-

-            case Type.LONG:

-                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

-                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

-                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

-

-                l0 = new Label();

-                mv.visitLabel(l0);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                l1 = new Label();

-                mv.visitJumpInsn(IFNE, l1);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

-                mv.visitInsn(LRETURN);

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-                mv.visitVarInsn(ASTORE, 1);

-

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitTypeInsn(CHECKCAST, boxingType);

-                mv.visitVarInsn(ASTORE, 2);

-

-                mv.visitVarInsn(ALOAD, 2);

-                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

-                mv.visitInsn(LRETURN);

-

-                break;

-

-            case Type.DOUBLE:

-                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

-                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

-                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

-

-                l0 = new Label();

-                mv.visitLabel(l0);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                l1 = new Label();

-                mv.visitJumpInsn(IFNE, l1);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

-                mv.visitInsn(DRETURN);

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-                mv.visitVarInsn(ASTORE, 1);

-

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitTypeInsn(CHECKCAST, boxingType);

-                mv.visitVarInsn(ASTORE, 2);

-

-                mv.visitVarInsn(ALOAD, 2);

-                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

-                mv.visitInsn(DRETURN);

-

-                break;

-

-            case Type.FLOAT:

-                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

-                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

-                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

-

-                l0 = new Label();

-                mv.visitLabel(l0);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                l1 = new Label();

-                mv.visitJumpInsn(IFNE, l1);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

-                mv.visitInsn(FRETURN);

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-                mv.visitVarInsn(ASTORE, 1);

-

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitTypeInsn(CHECKCAST, boxingType);

-                mv.visitVarInsn(ASTORE, 2);

-

-                mv.visitVarInsn(ALOAD, 2);

-                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

-                mv.visitInsn(FRETURN);

-

-                break;

-

-            case Type.OBJECT:

-                l0 = new Label();

-                mv.visitLabel(l0);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                l1 = new Label();

-                mv.visitJumpInsn(IFNE, l1);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");

-                mv.visitInsn(ARETURN);

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getterCallback", "(Ljava/lang/String;)Ljava/lang/Object;");

-                mv.visitTypeInsn(CHECKCAST, type.getInternalName());

-                mv.visitInsn(ARETURN);

-

-                break;

-

-            default:

-                ManipulationProperty.getLogger().log(ManipulationProperty.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_PRIVATE, "_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:

-                String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

-                String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

-

-                Label l1 = new Label();

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                Label l22 = new Label();

-                mv.visitJumpInsn(IFNE, l22);

-                

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

-                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);

-                mv.visitInsn(RETURN);

-                mv.visitLabel(l22);

-

-                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.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitVarInsn(ALOAD, 2);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-                Label l3 = new Label();

-                mv.visitLabel(l3);

-                mv.visitInsn(RETURN);

-                break;

-

-            case Type.LONG:

-            case Type.DOUBLE:

-                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

-                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

-

-                l1 = new Label();

-                mv.visitLabel(l1);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                Label l23 = new Label();

-                mv.visitJumpInsn(IFNE, l23);

-           

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

-                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);

-                mv.visitInsn(RETURN);

-                mv.visitLabel(l23);

-

-                mv.visitTypeInsn(NEW, boxingType);

-                mv.visitInsn(DUP);

-                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

-                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");

-                mv.visitVarInsn(ASTORE, 3); // Double space

-

-                l2 = new Label();

-                mv.visitLabel(l2);

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitVarInsn(ALOAD, 3);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-                l3 = new Label();

-                mv.visitLabel(l3);

-                mv.visitInsn(RETURN);

-                break;

-

-            case Type.OBJECT:

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_F" + name, "Z");

-                Label l24 = new Label();

-                mv.visitJumpInsn(IFNE, l24);

-           

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitFieldInsn(PUTFIELD, m_owner, name, "L" + type.getInternalName() + ";");

-                mv.visitInsn(RETURN);

-                mv.visitLabel(l24);

-

-                mv.visitVarInsn(ALOAD, 0);

-                mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-                mv.visitLdcInsn(name);

-                mv.visitVarInsn(ALOAD, 1);

-                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "setterCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-                mv.visitInsn(RETURN);

-                break;

-            default:

-                ManipulationProperty.getLogger().log(ManipulationProperty.SEVERE, "Manipulation Error : Cannot create the setter method for the field : " + name + " (" + type + ")");

-                break;

-        }

-

-        mv.visitMaxs(0, 0);

-        mv.visitEnd();

-    }

-}

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
index 1917582..da02b49 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/Manipulator.java
@@ -19,11 +19,8 @@
 package org.apache.felix.ipojo.manipulation;

 

 import java.io.ByteArrayInputStream;

-import java.io.File;

-import java.io.FileOutputStream;

 import java.io.IOException;

 import java.io.InputStream;

-import java.net.URL;

 import java.util.Iterator;

 import java.util.List;

 import java.util.Map;

@@ -60,73 +57,6 @@
     private String m_superClass;

 

     /**

-     * Manipulate the class.

-     * 

-     * @param name : The name of the class

-     * @param outputDirectory : output directory where the class if stored.

-     * @return true if the class is correctly manipulated.

-     * @throws Exception : occurs if the manipulation failed.

-     */

-    public boolean manipulate(String name, File outputDirectory) throws Exception {

-        // gets an input stream to read the byte code of the class

-        String path = outputDirectory + "/" + name.replace('.', '/') + ".class";

-        File clazz = new File(path);

-

-        if (!clazz.exists()) {

-            return false;

-        }

-

-        URL url = clazz.toURL();

-

-        // if (url == null) { throw new ClassNotFoundException(name); }

-        ManipulationProperty.getLogger().log(ManipulationProperty.INFO, "Manipulate the class file : " + clazz.getAbsolutePath());

-

-        InputStream is1 = url.openStream();

-

-        // First check if the class is already manipulated :

-        ClassReader ckReader = new ClassReader(is1);

-        ClassChecker ck = new ClassChecker();

-        ckReader.accept(ck, ClassReader.SKIP_FRAMES);

-        is1.close();

-

-        m_fields = ck.getFields(); // Get visited fields (contains only POJO fields)

-

-        // Get interfaces and super class.

-        m_interfaces = ck.getInterfaces();

-        m_superClass = ck.getSuperClass();

-

-        // Get the methods list

-        m_methods = ck.getMethods();

-

-        if (!ck.isalreadyManipulated()) {

-

-            // Manipulation ->

-            // Add the _setComponentManager method

-            // Instrument all fields

-            InputStream is2 = url.openStream();

-            ClassReader cr0 = new ClassReader(is2);

-            ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);

-            PojoAdapter preprocess = new PojoAdapter(cw0, m_fields);

-            cr0.accept(preprocess, ClassReader.SKIP_FRAMES);

-            is2.close();

-

-            try {

-                FileOutputStream fos = new FileOutputStream(clazz);

-

-                fos.write(cw0.toByteArray());

-

-                fos.close();

-                ManipulationProperty.getLogger().log(ManipulationProperty.INFO, "Put the file " + clazz.getAbsolutePath() + " in the jar file");

-            } catch (Exception e) {

-                System.err.println("Problem to write the adapted class on the file system " + " [ " + clazz.getAbsolutePath() + " ] " + e.getMessage());

-                e.printStackTrace();

-            }

-        }

-        // The file is in the bundle

-        return true;

-    }

-

-    /**

      * Manipulate the given byte array.

      * @param origin : original class.

      * @return the manipulated class.

@@ -158,7 +88,8 @@
             InputStream is2 = new ByteArrayInputStream(origin);

             ClassReader cr0 = new ClassReader(is2);

             ClassWriter cw0 = new ClassWriter(ClassWriter.COMPUTE_MAXS);

-            PojoAdapter preprocess = new PojoAdapter(cw0, m_fields);

+            //CheckClassAdapter ch = new CheckClassAdapter(cw0);

+            MethodCreator preprocess = new MethodCreator(cw0, m_fields);

             cr0.accept(preprocess, ClassReader.SKIP_FRAMES);

             is2.close();

             finalWriter = cw0;

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java
index d8be885..ff7d096 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCodeAdapter.java
@@ -20,28 +20,21 @@
 

 import java.util.Set;

 

-import org.objectweb.asm.Label;

 import org.objectweb.asm.MethodVisitor;

 import org.objectweb.asm.Opcodes;

-import org.objectweb.asm.Type;

-import org.objectweb.asm.commons.AdviceAdapter;

+import org.objectweb.asm.commons.GeneratorAdapter;

 

 /**

  * Insert code calling callbacks at the entry and before the exit of a method.

  * Moreover it replaces all GETFIELD and SETFIELD by getter and setter invocation.

  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

  */

-public class MethodCodeAdapter extends AdviceAdapter implements Opcodes {

+public class MethodCodeAdapter extends GeneratorAdapter implements Opcodes {

 

     /**

      * The owner class of the field. m_owner : String

      */

     private String m_owner;

-

-    /**

-     * Name of the method.

-     */

-    private String m_name;

     

     /**

      * Contained fields.

@@ -60,7 +53,6 @@
     public MethodCodeAdapter(final MethodVisitor mv, final String owner, int access, String name, String desc, Set fields) {

         super(mv, access, name, desc);

         m_owner = owner;

-        m_name = name;

         m_fields = fields;

     }

 

@@ -76,106 +68,15 @@
         if (owner.equals(m_owner) && m_fields.contains(name)) {

             if (opcode == GETFIELD) {

                 String gDesc = "()" + desc;

-                visitMethodInsn(INVOKESPECIAL, owner, "_get" + name, gDesc);

+                visitMethodInsn(INVOKESPECIAL, owner, "__get" + name, gDesc);

                 return;

             } else if (opcode == PUTFIELD) {

                 String sDesc = "(" + desc + ")V";

-                visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);

+                visitMethodInsn(INVOKESPECIAL, owner, "__set" + name, sDesc);

                 return;

             }

         }

         super.visitFieldInsn(opcode, owner, name, desc);

     }

 

-    /**

-     * Method injecting call at the entry of each method.

-     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodEnter()

-     */

-    protected void onMethodEnter() {

-        Type[] args = Type.getArgumentTypes(methodDesc);

-        String name = m_name;

-        

-        for (int i = 0; i < args.length; i++) {

-            String cn = args[i].getClassName();

-            if (cn.endsWith("[]")) {

-                cn = cn.replace('[', '$');

-                cn = cn.substring(0, cn.length() - 1);

-            }

-            cn = cn.replace('.', '_');

-            name += cn;

-        }

-

-        String flag = "_M" + name;

-

-        Label l0 = new Label();

-        mv.visitLabel(l0);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");

-        Label l1 = new Label();

-        mv.visitJumpInsn(IFEQ, l1);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "entryCallback", "(Ljava/lang/String;)V");

-        mv.visitLabel(l1);

-    }

-

-    /**

-     * Method injecting call at the exit of each method.

-     * @param opcode : returned opcode (ARETURN, IRETURN, ATHROW ...)

-     * @see org.objectweb.asm.commons.AdviceAdapter#onMethodExit(int)

-     */

-    protected void onMethodExit(int opcode) {

-        Type[] args = Type.getArgumentTypes(methodDesc);

-        String name = m_name;

-       

-        for (int i = 0; i < args.length; i++) {

-            String cn = args[i].getClassName();

-            if (cn.endsWith("[]")) {

-                cn = cn.replace('[', '$');

-                cn = cn.substring(0, cn.length() - 1);

-            }

-            cn = cn.replace('.', '_');

-            name += cn;

-        }

-

-        String flag = "_M" + name;

-

-        int local = newLocal(Type.getType(Object.class));

-        if (opcode == RETURN) {

-            visitInsn(ACONST_NULL);

-        } else if (opcode != ARETURN && opcode != ATHROW) {

-            box(Type.getReturnType(this.methodDesc));

-        }

-        

-        mv.visitVarInsn(ASTORE, local);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, flag, "Z");

-        Label l5 = new Label();

-        mv.visitJumpInsn(IFEQ, l5);

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitLdcInsn(name);

-        mv.visitVarInsn(ALOAD, local);

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "exitCallback", "(Ljava/lang/String;Ljava/lang/Object;)V");

-

-        mv.visitLabel(l5);

-        if (opcode == ARETURN || opcode == ATHROW) {

-            mv.visitVarInsn(ALOAD, local);

-        } else if (opcode != RETURN) {

-            mv.visitVarInsn(ALOAD, local);

-            unbox(Type.getReturnType(this.methodDesc));

-        }

-    }

-

-    /**

-     * Compute max local and max stack size.

-     * @param maxStack : new stack size.

-     * @param maxLocals : max local (do not modified, super will update it automatically).

-     * @see org.objectweb.asm.commons.LocalVariablesSorter#visitMaxs(int, int)

-     */

-    public void visitMaxs(int maxStack, int maxLocals) {

-        super.visitMaxs(maxStack + 1, maxLocals);

-    }

-

 }

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
new file mode 100644
index 0000000..348f883
--- /dev/null
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
@@ -0,0 +1,940 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.manipulation;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+

+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;

+import org.objectweb.asm.commons.GeneratorAdapter;

+

+/**

+ * iPOJO Class Adapter.

+ * This class adapt the visited class to link the class with the container.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class MethodCreator extends ClassAdapter implements Opcodes {

+

+    /**

+     * Instance Manager Field.

+     */

+    public static final  String IM_FIELD = "__IM";

+    

+    /**

+     * All POJO method will be renamed by using this prefix.

+     */

+    private static final String PREFIX = "__";

+

+    /**

+     * POJO class.

+     */

+    private static final  String POJO = "org/apache/felix/ipojo/Pojo";

+

+    /**

+     * Filed flag prefix.

+     */

+    private static final  String FIELD_FLAG_PREFIX = "__F";

+

+    /**

+     * MEthof flag prefix.

+     */

+    private static final  String METHOD_FLAG_PREFIX = "__M";

+

+    /**

+     * onEntry method name.

+     */

+    private static final  String ENTRY = "onEntry";

+

+    /**

+     * onExit method name. 

+     */

+    private static final  String EXIT = "onExit";

+

+    /**

+     * on Error method name.

+     */

+    private static final  String ERROR = "onError";

+

+    /**

+     * onGet method name. 

+     */

+    private static final  String GET = "onGet";

+

+    /**

+     * onSet method name.

+     */

+    private static final  String SET = "onSet";

+

+    /**

+     * Name of the current manipulated class. 

+     */

+    private String m_owner;

+

+    /**

+     * Set of fields detected in the class.

+     * (this set is given by the previous analysis)

+     */

+    private Set m_fields;

+

+    /**

+     * List of methods contained in the class.

+     * This set contains method id.

+     */

+    private List m_methods = new ArrayList(); // Contains method id.

+

+    /**

+     * Constructor.

+     * @param arg0 : class visitor.

+     * @param fields : fields map detected during the previous class analysis.

+     */

+    public MethodCreator(ClassVisitor arg0, Map fields) {

+        super(arg0);

+        m_fields = fields.keySet();

+    }

+

+    /**

+     * Vist method.

+     * This method store the current class name.

+     * Moreover the POJO interface is added to the list of implemented interface.

+     * Then the Instance manager field is added.

+     * @param version : version

+     * @param access : access flag

+     * @param name : class name

+     * @param signature : signature

+     * @param superName : parent class

+     * @param interfaces : implemented interface

+     * @see org.objectweb.asm.ClassAdapter#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])

+     */

+    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {

+        m_owner = name;

+        addPOJOInterface(version, access, name, signature, superName, interfaces);

+        addIMField();

+    }

+

+    /**

+     * A method is visited.

+     * This method does not manipulate clinit and class$ methods.

+     * In the case of a constructor, this method will generate a constructor with the instance manager 

+     * and will adapt the current constructor to call this constructor.

+     * For standard method, this method will create method header, rename the current method and adapt it.

+     * @param access : access flag.

+     * @param name : name of the method

+     * @param desc : method descriptor

+     * @param signature : signature

+     * @param exceptions : declared exceptions.

+     * @return the MethodVisitor wichi will visit the method code.

+     * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])

+     */

+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

+        // Avoid manipulating special methods

+        if (name.equals("<clinit>") || name.equals("class$")) { return super.visitMethod(access, name, desc, signature, exceptions); }

+        // The constructor is manipulated separately

+        if (name.equals("<init>")) {

+            //TODO : do not manipulate non matching constructor.

+            

+            

+            // 1) change the constructor descriptor (add a component manager arg as first argument)

+            String newDesc = desc.substring(1);

+            newDesc = "(Lorg/apache/felix/ipojo/InstanceManager;" + newDesc;

+

+            Type[] args = Type.getArgumentTypes(desc);

+            if (args.length == 0) {

+                generateEmptyConstructor(access, signature, exceptions);

+            } else if (args.length == 1 && args[0].getClassName().equals("org.osgi.framework.BundleContext")) {

+                generateBCConstructor(access, signature, exceptions);

+            } else {

+                // Do nothing, the constructor does not match.

+                return cv.visitMethod(access, name, desc, signature, exceptions);

+            }

+

+            // Insert the new constructor

+            MethodVisitor mv = super.visitMethod(ACC_PRIVATE, "<init>", newDesc, signature, exceptions);

+            return new ConstructorCodeAdapter(mv, m_owner, m_fields, ACC_PRIVATE, name, newDesc);

+        }

+

+        if ((access & ACC_STATIC) == ACC_STATIC) { return super.visitMethod(access, name, desc, signature, exceptions); }

+

+        generateMethodHeader(access, name, desc, signature, exceptions);

+        FieldVisitor flagField = cv.visitField(Opcodes.ACC_PRIVATE, generateMethodFlag(name, desc), "Z", null, null);

+        flagField.visitEnd();

+

+        MethodVisitor mv = super.visitMethod(ACC_PRIVATE, PREFIX + name, desc, signature, exceptions);

+        return new MethodCodeAdapter(mv, m_owner, ACC_PRIVATE, PREFIX + name, desc, m_fields);

+    }

+

+    /**

+     * Visit a Field.

+     * This field access is replaced by an invocation to the getter method or to the setter method.

+     * (except for static field).

+     * Inject the getter and the setter method for this field.

+     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)

+     * @param access : access 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 : null

+     */

+    public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {

+        if ((access & ACC_STATIC) == 0) {

+            FieldVisitor flag = cv.visitField(Opcodes.ACC_PRIVATE, FIELD_FLAG_PREFIX + name, "Z", null, null);

+            flag.visitEnd();

+

+            Type type = Type.getType(desc);

+

+            if (type.getSort() == Type.ARRAY) {

+                String gDesc = "()" + desc;

+                createArrayGetter(name, gDesc, type);

+

+                // Generates setter method

+                String sDesc = "(" + desc + ")V";

+                createArraySetter(name, sDesc, type);

+

+            } else {

+                // Generate the getter method

+                String gDesc = "()" + desc;

+                createSimpleGetter(name, gDesc, type);

+

+                // Generates setter method

+                String sDesc = "(" + desc + ")V";

+                createSimpleSetter(name, sDesc, type);

+            }

+

+        }

+        return cv.visitField(access, name, desc, signature, value);

+    }

+

+    /**

+     * Create a constructor to call the manipulated constructor.

+     * This constructor does not have any argument. It will call the manipulated

+     * constructor with a null instance manager.

+     * @param access : access flag

+     * @param signature : method signature

+     * @param exceptions : declared exception

+     */

+    private void generateEmptyConstructor(int access, String signature, String[] exceptions) {

+        MethodVisitor mv = cv.visitMethod(access, "<init>", "()V", signature, exceptions);

+        mv.visitCode();

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitInsn(ACONST_NULL);

+        mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;)V");

+        mv.visitInsn(RETURN);

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Create a constructor to call the manipulated constructor.

+     * This constructor has one argument (the bundle context). It will call the manipulated

+     * constructor with a null instance manager.

+     * @param access : access flag

+     * @param signature : method signature

+     * @param exceptions : declared exception

+     */

+    private void generateBCConstructor(int access, String signature, String[] exceptions) {

+        MethodVisitor mv = cv.visitMethod(access, "<init>", "(Lorg/osgi/framework/BundleContext;)V", signature, exceptions);

+        mv.visitCode();

+        Label l0 = new Label();

+        mv.visitLabel(l0);

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitInsn(ACONST_NULL);

+        mv.visitVarInsn(ALOAD, 1);

+        mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(Lorg/apache/felix/ipojo/InstanceManager;Lorg/osgi/framework/BundleContext;)V");

+        mv.visitInsn(RETURN);

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Generate the method header of a POJO method.

+     * This method header encapsulate the POJO method call to

+     * signal entry exit and error to the container.

+     * @param access : access flag.

+     * @param name : method name.

+     * @param desc : method descriptor.

+     * @param signature : method signature.

+     * @param exceptions : declared exceptions.

+     */

+    private void generateMethodHeader(int access, String name, String desc, String signature, String[] exceptions) {

+        GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc); 

+        

+        mv.visitCode();

+        Type returnType = Type.getReturnType(desc);

+

+        // Compute result and exception stack location

+        int result = -1;

+        int exception = -1;

+        

+        //int arguments = mv.newLocal(Type.getType((new Object[0]).getClass()));

+

+        if (returnType.getSort() != Type.VOID) {

+            // The method returns something 

+            result = mv.newLocal(returnType);

+            exception = mv.newLocal(Type.getType(Throwable.class));

+        } else {

+            exception = mv.newLocal(Type.getType(Throwable.class));

+        }

+

+        Label l0 = new Label();

+        Label l1 = new Label();

+        Label l2 = new Label();

+

+        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, generateMethodFlag(name, desc), "Z");

+        mv.visitJumpInsn(IFNE, l0);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.loadArgs();

+        mv.visitMethodInsn(INVOKESPECIAL, m_owner, PREFIX + name, desc);

+        mv.visitInsn(returnType.getOpcode(IRETURN));

+

+        // end of the non intercepted method invocation.

+        

+        mv.visitLabel(l0);

+        

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitLdcInsn(generateMethodId(name, desc));

+        mv.loadArgArray();

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ENTRY, "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");

+        

+        mv.visitVarInsn(ALOAD, 0);

+            

+        // Do not allow argument modification : just reload arguments.

+        mv.loadArgs();

+        mv.visitMethodInsn(INVOKESPECIAL, m_owner, PREFIX + name, desc);

+

+        if (returnType.getSort() != Type.VOID) {

+            mv.visitVarInsn(returnType.getOpcode(ISTORE), result);

+        }

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitLdcInsn(generateMethodId(name, desc));

+        if (returnType.getSort() != Type.VOID) {

+            mv.visitVarInsn(returnType.getOpcode(ILOAD), result);

+            mv.box(returnType);

+        } else {

+            mv.visitInsn(ACONST_NULL);

+        }

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", EXIT, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

+        

+        mv.visitLabel(l1);

+        Label l7 = new Label();

+        mv.visitJumpInsn(GOTO, l7);

+        mv.visitLabel(l2);

+

+        mv.visitVarInsn(ASTORE, exception);

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitLdcInsn(generateMethodId(name, desc));

+        mv.visitVarInsn(ALOAD, exception);

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ERROR, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Throwable;)V");

+        mv.visitVarInsn(ALOAD, exception);

+        mv.visitInsn(ATHROW);

+

+        mv.visitLabel(l7);

+        if (returnType.getSort() != Type.VOID) {

+            mv.visitVarInsn(returnType.getOpcode(ILOAD), result);

+        }

+        mv.visitInsn(returnType.getOpcode(IRETURN));

+

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Generate a method flag name.

+     * @param name : method name.

+     * @param desc : method descriptor.

+     * @return the method flag name.

+     */

+    private String generateMethodFlag(String name, String desc) {

+        return METHOD_FLAG_PREFIX + generateMethodId(name, desc);

+    }

+

+    /**

+     * Generate the method id based on the given method name and method descriptor.

+     * The method Id is unique for this method and serves to create the flag field (so

+     * must follow field name Java restrictions).

+     * @param name : method name

+     * @param desc : method descriptor

+     * @return  method ID

+     */

+    private String generateMethodId(String name, String desc) {

+        String id = name;

+        Type[] args = Type.getArgumentTypes(desc);

+        for (int i = 0; i < args.length; i++) {

+            String arg = args[i].getClassName();

+            if (arg.endsWith("[]")) {

+                arg = arg.substring(0, arg.length() - 2);

+                id += "$" + arg.replace('.', '_') + "__";

+            } else {

+                id += "$" + arg.replace('.', '_');

+            }

+        }

+        if (!m_methods.contains(id)) {

+            m_methods.add(id);

+        }

+        return id;

+    }

+

+    /**

+     * Add the instance manager field (__im).

+     */

+    private void addIMField() {

+        FieldVisitor fv = super.visitField(ACC_PRIVATE, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;", null, null);

+        fv.visitEnd();

+    }

+

+    /**

+     * Add the POJO interface to the visited class.

+     * @param version : class version

+     * @param access : class access

+     * @param name : class name

+     * @param signature : class signature

+     * @param superName : super class

+     * @param interfaces : implemented interfaces.

+     */

+    private void addPOJOInterface(int version, int access, String name, String signature, String superName, String[] interfaces) {

+

+        // Add the POJO interface to the interface list

+        // Check that the POJO interface is not already in the list

+        boolean found = false;

+        for (int i = 0; i < interfaces.length; i++) {

+            if (interfaces[i].equals(POJO)) {

+                found = true;

+            }

+        }

+        String[] itfs;

+        if (!found) {

+            itfs = new String[interfaces.length + 1];

+            for (int i = 0; i < interfaces.length; i++) {

+                itfs[i] = interfaces[i];

+            }

+            itfs[interfaces.length] = POJO;

+        } else {

+            itfs = interfaces;

+        }

+

+        String str = "";

+        for (int i = 0; i < itfs.length; i++) {

+            str += itfs[i] + " ";

+        }

+

+        cv.visit(version, access, name, signature, superName, itfs);

+    }

+

+    /**

+     * Visit end.

+     * Create helper methods.

+     * @see org.objectweb.asm.ClassAdapter#visitEnd()

+     */

+    public void visitEnd() {

+        // Create the component manager setter method

+        createSetInstanceManagerMethod();

+

+        // Add the getComponentInstance

+        createGetComponentInstanceMethod();

+

+        m_methods.clear();

+

+        cv.visitEnd();

+    }

+

+    /**

+     * Create the setter method for the __cm field.

+     */

+    private void createSetInstanceManagerMethod() {

+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_setInstanceManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V", null, null);

+        mv.visitCode();

+

+        // If the given instance manager is null, just returns.

+        mv.visitVarInsn(ALOAD, 1);

+        Label l1 = new Label();

+        mv.visitJumpInsn(IFNONNULL, l1);

+        mv.visitInsn(RETURN);

+        mv.visitLabel(l1);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitVarInsn(ALOAD, 1);

+        mv.visitFieldInsn(PUTFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredFields", "()Ljava/util/Set;");

+        mv.visitVarInsn(ASTORE, 2);

+

+        mv.visitVarInsn(ALOAD, 2);

+        Label endif = new Label();

+        mv.visitJumpInsn(IFNULL, endif);

+        Iterator it = m_fields.iterator();

+        while (it.hasNext()) {

+            String field = (String) it.next();

+            mv.visitVarInsn(ALOAD, 2);

+            mv.visitLdcInsn(field);

+            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");

+            Label l3 = new Label();

+            mv.visitJumpInsn(IFEQ, l3);

+            mv.visitVarInsn(ALOAD, 0);

+            mv.visitInsn(ICONST_1);

+            mv.visitFieldInsn(PUTFIELD, m_owner, FIELD_FLAG_PREFIX + field, "Z");

+            mv.visitLabel(l3);

+        }

+        mv.visitLabel(endif);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredMethods", "()Ljava/util/Set;");

+        mv.visitVarInsn(ASTORE, 2);

+

+        mv.visitVarInsn(ALOAD, 2);

+        Label endif2 = new Label();

+        mv.visitJumpInsn(IFNULL, endif2);

+

+        for (int i = 0; i < m_methods.size(); i++) {

+            String methodId = (String) m_methods.get(i);

+            if (!methodId.equals("<init>")) {

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitLdcInsn(methodId);

+                mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");

+                Label l3 = new Label();

+                mv.visitJumpInsn(IFEQ, l3);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitInsn(ICONST_1);

+                mv.visitFieldInsn(PUTFIELD, m_owner, METHOD_FLAG_PREFIX + methodId, "Z");

+                mv.visitLabel(l3);

+            }

+        }

+

+        mv.visitLabel(endif2);

+

+        mv.visitInsn(RETURN);

+

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Create the getComponentInstance method.

+     */

+    private void createGetComponentInstanceMethod() {

+        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getComponentInstance", "()Lorg/apache/felix/ipojo/ComponentInstance;", null, null);

+        mv.visitCode();

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitInsn(ARETURN);

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Create a getter method for an array.

+     * @param name : field name

+     * @param desc : method description

+     * @param type : contained type (inside the array)

+     */

+    private void createArraySetter(String name, String desc, Type type) {

+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "__set" + name, desc, null, null);

+        mv.visitCode();

+

+        String internalType = desc.substring(1);

+        internalType = internalType.substring(0, internalType.length() - 2);

+

+        Label l1 = new Label();

+        mv.visitLabel(l1);

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+        Label l2 = new Label();

+        mv.visitJumpInsn(IFNE, l2);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitVarInsn(ALOAD, 1);

+        mv.visitFieldInsn(PUTFIELD, m_owner, name, internalType);

+        mv.visitInsn(RETURN);

+        mv.visitLabel(l2);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitLdcInsn(name);

+        mv.visitVarInsn(ALOAD, 1);

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", SET, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

+

+        mv.visitInsn(RETURN);

+

+        // End

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Create a setter method for an array.

+     * @param name : field name

+     * @param desc : method description

+     * @param type : contained type (inside the array)

+     */

+    private void createArrayGetter(String name, String desc, Type type) {

+        String methodName = "__get" + name;

+        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, methodName, desc, null, null);

+        mv.visitCode();

+

+        String internalType = desc.substring(2);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+        Label l1 = new Label();

+        mv.visitJumpInsn(IFNE, l1);

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, name, internalType);

+        mv.visitInsn(ARETURN);

+        mv.visitLabel(l1);

+

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+        mv.visitVarInsn(ALOAD, 0);

+        mv.visitLdcInsn(name);

+        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+        mv.visitTypeInsn(CHECKCAST, internalType);

+        mv.visitInsn(ARETURN);

+

+        // End

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+    /**

+     * Create the getter for a field.

+     * @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_PRIVATE, methodName, desc, null, null);

+        mv.visitCode();

+

+        switch (type.getSort()) {

+            case Type.BOOLEAN:

+            case Type.CHAR:

+            case Type.BYTE:

+            case Type.SHORT:

+            case Type.INT:

+

+                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];

+

+                Label l0 = new Label();

+                mv.visitLabel(l0);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                Label l1 = new Label();

+                mv.visitJumpInsn(IFNE, l1);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

+                mv.visitInsn(IRETURN);

+

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+                mv.visitVarInsn(ASTORE, 1);

+

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitTypeInsn(CHECKCAST, boxingType);

+                mv.visitVarInsn(ASTORE, 2);

+

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

+                mv.visitInsn(type.getOpcode(IRETURN));

+                break;

+

+            case Type.LONG:

+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

+

+                l0 = new Label();

+                mv.visitLabel(l0);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                l1 = new Label();

+                mv.visitJumpInsn(IFNE, l1);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

+                mv.visitInsn(LRETURN);

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+                mv.visitVarInsn(ASTORE, 1);

+

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitTypeInsn(CHECKCAST, boxingType);

+                mv.visitVarInsn(ASTORE, 2);

+

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

+                mv.visitInsn(LRETURN);

+

+                break;

+

+            case Type.DOUBLE:

+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

+

+                l0 = new Label();

+                mv.visitLabel(l0);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                l1 = new Label();

+                mv.visitJumpInsn(IFNE, l1);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

+                mv.visitInsn(DRETURN);

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+                mv.visitVarInsn(ASTORE, 1);

+

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitTypeInsn(CHECKCAST, boxingType);

+                mv.visitVarInsn(ASTORE, 2);

+

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

+                mv.visitInsn(DRETURN);

+

+                break;

+

+            case Type.FLOAT:

+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

+                unboxingMethod = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][2];

+

+                l0 = new Label();

+                mv.visitLabel(l0);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                l1 = new Label();

+                mv.visitJumpInsn(IFNE, l1);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, name, internalName);

+                mv.visitInsn(FRETURN);

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+                mv.visitVarInsn(ASTORE, 1);

+

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitTypeInsn(CHECKCAST, boxingType);

+                mv.visitVarInsn(ASTORE, 2);

+

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitMethodInsn(INVOKEVIRTUAL, boxingType, unboxingMethod, "()" + internalName);

+                mv.visitInsn(FRETURN);

+

+                break;

+

+            case Type.OBJECT:

+                l0 = new Label();

+                mv.visitLabel(l0);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                l1 = new Label();

+                mv.visitJumpInsn(IFNE, l1);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, name, "L" + type.getInternalName() + ";");

+                mv.visitInsn(ARETURN);

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", GET, "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");

+                mv.visitTypeInsn(CHECKCAST, type.getInternalName());

+                mv.visitInsn(ARETURN);

+

+                break;

+

+            default:

+                ManipulationProperty.getLogger().log(ManipulationProperty.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_PRIVATE, "__set" + name, desc, null, null);

+        mv.visitCode();

+

+        switch (type.getSort()) {

+            case Type.BOOLEAN:

+            case Type.CHAR:

+            case Type.BYTE:

+            case Type.SHORT:

+            case Type.INT:

+            case Type.FLOAT:

+                String internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

+                String boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

+

+                Label l1 = new Label();

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                Label l22 = new Label();

+                mv.visitJumpInsn(IFNE, l22);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

+                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);

+                mv.visitInsn(RETURN);

+                mv.visitLabel(l22);

+

+                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.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitVarInsn(ALOAD, 2);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", SET, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

+

+                Label l3 = new Label();

+                mv.visitLabel(l3);

+                mv.visitInsn(RETURN);

+                break;

+

+            case Type.LONG:

+            case Type.DOUBLE:

+                internalName = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][0];

+                boxingType = ManipulationProperty.PRIMITIVE_BOXING_INFORMATION[type.getSort()][1];

+

+                l1 = new Label();

+                mv.visitLabel(l1);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                Label l23 = new Label();

+                mv.visitJumpInsn(IFNE, l23);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

+                mv.visitFieldInsn(PUTFIELD, m_owner, name, internalName);

+                mv.visitInsn(RETURN);

+                mv.visitLabel(l23);

+

+                mv.visitTypeInsn(NEW, boxingType);

+                mv.visitInsn(DUP);

+                mv.visitVarInsn(type.getOpcode(ILOAD), 1);

+                mv.visitMethodInsn(INVOKESPECIAL, boxingType, "<init>", "(" + internalName + ")V");

+                mv.visitVarInsn(ASTORE, 3); // Double space

+

+                l2 = new Label();

+                mv.visitLabel(l2);

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitVarInsn(ALOAD, 3);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", SET, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

+

+                l3 = new Label();

+                mv.visitLabel(l3);

+                mv.visitInsn(RETURN);

+                break;

+

+            case Type.OBJECT:

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, FIELD_FLAG_PREFIX + name, "Z");

+                Label l24 = new Label();

+                mv.visitJumpInsn(IFNE, l24);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitFieldInsn(PUTFIELD, m_owner, name, "L" + type.getInternalName() + ";");

+                mv.visitInsn(RETURN);

+                mv.visitLabel(l24);

+

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitFieldInsn(GETFIELD, m_owner, IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");

+                mv.visitVarInsn(ALOAD, 0);

+                mv.visitLdcInsn(name);

+                mv.visitVarInsn(ALOAD, 1);

+                mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", SET, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V");

+

+                mv.visitInsn(RETURN);

+                break;

+            default:

+                ManipulationProperty.getLogger().log(ManipulationProperty.SEVERE, "Manipulation Error : Cannot create the setter method for the field : " + name + " (" + type + ")");

+                break;

+        }

+

+        mv.visitMaxs(0, 0);

+        mv.visitEnd();

+    }

+

+}

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
deleted file mode 100644
index 41ca684..0000000
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/* 

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you under the Apache License, Version 2.0 (the

- * "License"); you may not use this file except in compliance

- * with the License.  You may obtain a copy of the License at

- *

- *   http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing,

- * software distributed under the License is distributed on an

- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

- * KIND, either express or implied.  See the License for the

- * specific language governing permissions and limitations

- * under the License.

- */

-package org.apache.felix.ipojo.manipulation;

-

-import java.util.ArrayList;

-import java.util.Iterator;

-import java.util.List;

-import java.util.Map;

-import java.util.Set;

-

-import org.objectweb.asm.AnnotationVisitor;

-import org.objectweb.asm.Attribute;

-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 a POJO class.

- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

- */

-public class PojoAdapter extends ClassAdapter implements Opcodes {

-

-    /**

-     * POJO interface.

-     */

-    private final String m_pojo = "org/apache/felix/ipojo/Pojo";

-

-    /**

-     * The owner. m_owner : String

-     */

-    private String m_owner;

-

-    /**

-     * Field list.

-     */

-    private Set m_fields;

-    

-

-    /**

-     * Method list.

-     */

-    private List m_methods = new ArrayList();

-

-    /**

-     * Getter/Setter methods creator.

-     */

-    private FieldAdapter m_getterSetterCreator = new FieldAdapter(cv);

-

-    /**

-     * Constructor.

-     * @param arg0 : class adapter on which delegate.

-     * @param fields : map of contained fields.

-     * @param m_fields2 

-     */

-    public PojoAdapter(ClassVisitor arg0, Map fields) {

-        super(arg0);

-        m_fields = fields.keySet();

-    }

-

-    /**

-     * Start visiting a class.

-     * Initialize the getter/setter generator, add the _cm field, add the pojo interface.

-     * @param version : class version

-     * @param access : class access

-     * @param name : class name 

-     * @param signature : class signature

-     * @param superName : class super class

-     * @param interfaces : implemented interfaces

-     * @see org.objectweb.asm.ClassAdapter#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])

-     */

-    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {

-        m_owner = name;

-        m_getterSetterCreator.visit(version, access, name, signature, superName, interfaces);

-        addCMField();

-        addPOJOInterface(version, access, name, signature, superName, interfaces);

-    }

-

-    /**

-     * Visit an annotation.

-     * @param desc : annotation descriptor.

-     * @param visible : is the annotation visible at runtime.

-     * @return the annotation visitor.

-     * @see org.objectweb.asm.ClassAdapter#visitAnnotation(java.lang.String, boolean)

-     */

-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {

-        return super.visitAnnotation(desc, visible);

-    }

-

-    /**

-     * Visit an attribute.

-     * @param attr : visited attribute

-     * @see org.objectweb.asm.ClassAdapter#visitAttribute(org.objectweb.asm.Attribute)

-     */

-    public void visitAttribute(Attribute attr) {

-        super.visitAttribute(attr);

-    }

-

-    /**

-     * Visit end.

-     * Create helper methods.

-     * @see org.objectweb.asm.ClassAdapter#visitEnd()

-     */

-    public void visitEnd() {

-        // Create the _cmSetter(ComponentManager cm) method

-        createComponentManagerSetter();

-

-        // Add the getComponentInstance

-        createGetComponentInstanceMethod();

-

-        m_methods.clear();

-

-        cv.visitEnd();

-    }

-

-    /**

-     * Visit a field.

-     * Call the adapter generating getter and setter methods.

-     * @param access : field access.

-     * @param name : field name

-     * @param desc : field descriptor

-     * @param signature : field signature

-     * @param value : field value (static field only)

-     * @return the field visitor.

-     * @see org.objectweb.asm.ClassAdapter#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)

-     */

-    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {

-        // Add the field to the list.

-        if (((access & ACC_STATIC) == 0) && (!name.startsWith("class$"))) {

-            addFlagField(name);

-            m_getterSetterCreator.visitField(access, name, desc, signature, value);

-        }

-

-        return super.visitField(access, name, desc, signature, value);

-    }

-

-    /**

-     * Visit an inner class.

-     * @param name : class name

-     * @param outerName : outer name

-     * @param innerName : inner name

-     * @param access : class access

-     * @see org.objectweb.asm.ClassAdapter#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)

-     */

-    public void visitInnerClass(String name, String outerName, String innerName, int access) {

-        super.visitInnerClass(name, outerName, innerName, access);

-    }

-

-    /**

-     * Visit a method.

-     * Manipulate constructor and methods. Does nothing with clinit and class$

-     * @param access : method access

-     * @param name : method name

-     * @param desc : method descriptor

-     * @param signature : method signature

-     * @param exceptions : method exceptions

-     * @return the Method Visitor.

-     * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])

-     */

-    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

-        // Avoid manipulating special method

-        if (name.equals("<clinit>") || name.equals("class$")) { return super.visitMethod(access, name, desc, signature, exceptions); }

-        // The constructor is manipulated separately

-        if (name.equals("<init>")) {      

-            

-            // 1) change the constructor descriptor (add a component manager arg as first argument)

-            String newDesc = desc.substring(1);

-            newDesc = "(Lorg/apache/felix/ipojo/InstanceManager;" + newDesc;

-

-            // Insert the new constructor

-            MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "<init>", newDesc, null, null);

-            

-            Type[] args = Type.getArgumentTypes(newDesc);

-            String id = "$init";

-            for (int i = 0; i < args.length; i++) {

-                String cn = args[i].getClassName();

-                if (cn.endsWith("[]")) {

-                    cn = cn.replace('[', '$');

-                    cn = cn.substring(0, cn.length() - 1);

-                }

-                cn = cn.replace('.', '_');

-                id += cn;

-            }

-

-            String flag = "_M" + id;

-            m_methods.add(id);

-

-            FieldVisitor flagField = cv.visitField(Opcodes.ACC_PRIVATE, flag, "Z", null, null);

-            if (flagField != null) {

-                flagField.visitEnd();

-            }

-

-            if (mv == null) {

-                return null;

-            } else {

-                return new ConstructorCodeAdapter(mv, m_owner, m_fields, access, name, newDesc);

-            }

-        } else { // "Normal methods"

-            // avoid manipulating static methods.

-            if ((access & ACC_STATIC) == ACC_STATIC) { return super.visitMethod(access, name, desc, signature, exceptions); }

-            

-            Type[] args = Type.getArgumentTypes(desc);

-            String id = name;

-            for (int i = 0; i < args.length; i++) {

-                String cn = args[i].getClassName();

-                if (cn.endsWith("[]")) {

-                    cn = cn.replace('[', '$');

-                    cn = cn.substring(0, cn.length() - 1);

-                }

-                cn = cn.replace('.', '_');

-                id += cn;

-            }

-

-            String flag = "_M" + id;

-            m_methods.add(id);

-

-            FieldVisitor flagField = cv.visitField(Opcodes.ACC_PRIVATE, flag, "Z", null, null);

-            if (flagField != null) {

-                flagField.visitEnd();

-            }

-

-            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);

-            return new MethodCodeAdapter(mv, m_owner, access, name, desc, m_fields);

-        }

-    }

-

-    /**

-     * Visit an outer class.

-     * @param owner : class owner

-     * @param name : class name

-     * @param desc : class descriptor.

-     * @see org.objectweb.asm.ClassAdapter#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)

-     */

-    public void visitOuterClass(String owner, String name, String desc) {

-        super.visitOuterClass(owner, name, desc);

-    }

-

-    /**

-     * Visit source.

-     * @param source : source

-     * @param debug : debug

-     * @see org.objectweb.asm.ClassAdapter#visitSource(java.lang.String, java.lang.String)

-     */

-    public void visitSource(String source, String debug) {

-        super.visitSource(source, debug);

-    }

-

-    /**

-     * Add the instance manager field (_cm).

-     */

-    private void addCMField() {

-        // Insert _cm field

-        FieldVisitor fv = super.visitField(ACC_PRIVATE, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;", null, null);

-        fv.visitEnd();

-    }

-

-    /**

-     * Add the POJO interface to the visited class.

-     * @param version : class version

-     * @param access : class access

-     * @param name : class name

-     * @param signature : class signature

-     * @param superName : super class

-     * @param interfaces : implemented interfaces.

-     */

-    private void addPOJOInterface(int version, int access, String name, String signature, String superName, String[] interfaces) {

-

-        // Add the POJO interface to the interface list

-        // Check that the POJO interface is not already in the list

-        boolean found = false;

-        for (int i = 0; i < interfaces.length; i++) {

-            if (interfaces[i].equals(m_pojo)) {

-                found = true;

-            }

-        }

-        String[] itfs;

-        if (!found) {

-            itfs = new String[interfaces.length + 1];

-            for (int i = 0; i < interfaces.length; i++) {

-                itfs[i] = interfaces[i];

-            }

-            itfs[interfaces.length] = m_pojo;

-        } else {

-            itfs = interfaces;

-        }

-

-        String str = "";

-        for (int i = 0; i < itfs.length; i++) {

-            str += itfs[i] + " ";

-        }

-

-        cv.visit(version, access, name, signature, superName, itfs);

-    }

-

-    /**

-     * Create the setter method for the _cm field.

-     */

-    private void createComponentManagerSetter() {

-        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "_setComponentManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V", null, null);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitVarInsn(ALOAD, 1);

-        mv.visitFieldInsn(PUTFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredFields", "()Ljava/util/Set;");

-        mv.visitVarInsn(ASTORE, 2);

-

-        mv.visitVarInsn(ALOAD, 2);

-        Label endif = new Label();

-        mv.visitJumpInsn(IFNULL, endif);

-        Iterator it = m_fields.iterator();

-        while (it.hasNext()) {

-            String field = (String) it.next();

-            mv.visitVarInsn(ALOAD, 2);

-            mv.visitLdcInsn(field);

-            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");

-            Label l3 = new Label();

-            mv.visitJumpInsn(IFEQ, l3);

-            mv.visitVarInsn(ALOAD, 0);

-            mv.visitInsn(ICONST_1);

-            mv.visitFieldInsn(PUTFIELD, m_owner, "_F" + field, "Z");

-            mv.visitLabel(l3);

-        }

-        mv.visitLabel(endif);

-        

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredMethods", "()Ljava/util/Set;");

-        mv.visitVarInsn(ASTORE, 2);

-        

-        mv.visitVarInsn(ALOAD, 2);

-        Label endif2 = new Label();

-        mv.visitJumpInsn(IFNULL, endif2);

-

-        for (int i = 0; i < m_methods.size(); i++) {

-            String methodId = (String) m_methods.get(i);

-            mv.visitVarInsn(ALOAD, 2);

-            mv.visitLdcInsn(methodId);

-            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z");

-            Label l3 = new Label();

-            mv.visitJumpInsn(IFEQ, l3);

-            mv.visitVarInsn(ALOAD, 0);

-            mv.visitInsn(ICONST_1);

-            mv.visitFieldInsn(PUTFIELD, m_owner, "_M" + methodId, "Z");

-            mv.visitLabel(l3);

-        }

-        

-        mv.visitLabel(endif2);

-

-        mv.visitInsn(RETURN);

-

-        mv.visitMaxs(0, 0);

-        mv.visitEnd();

-    }

-

-    /**

-     * Create the getComponentInstance method.

-     */

-    private void createGetComponentInstanceMethod() {

-        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getComponentInstance", "()Lorg/apache/felix/ipojo/ComponentInstance;", null, null);

-

-        mv.visitVarInsn(ALOAD, 0);

-        mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");

-        mv.visitInsn(ARETURN);

-

-        mv.visitMaxs(0, 0);

-        mv.visitEnd();

-    }

-

-    /**

-     * Add the flag field.

-     * @param name : name of the field

-     */

-    private void addFlagField(String name) {

-        // Add the flag field

-        FieldVisitor flag = cv.visitField(Opcodes.ACC_PRIVATE, "_F" + name, "Z", null, null);

-        if (flag != null) {

-            flag.visitEnd();

-        }

-    }

-

-}

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
index 7b68f69..a439e38 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
@@ -279,7 +279,7 @@
             

             Element[] props = m_parent.getElements("Property");

             Element prop = null;

-            for (int i = 0; prop == null && i < props.length; i++) {

+            for (int i = 0; prop == null && props != null && i < props.length; i++) {

                 String name = props[i].getAttribute("name");

                 if (name != null && name.equals(m_name)) {

                     prop = props[i];

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
index 9859888..0c5d53b 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
@@ -334,7 +334,7 @@
             }

             Element[] props = m_parent.getElements("Property");

             Element prop = null;

-            for (int i = 0; prop == null && i < props.length; i++) {

+            for (int i = 0; props != null && prop == null && i < props.length; i++) {

                 String name = props[i].getAttribute("name");

                 if (name != null && name.equals(m_name)) {

                     prop = props[i];

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index b78666f..6537861 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -133,6 +133,9 @@
                 path = "/" + path;

             }

             m_metadata = parseXMLMetadata(path);

+            if (m_metadata == null) {

+                return;

+            }

         }

         

         JarFile inputJar;

@@ -422,7 +425,7 @@
     private void setImports(Attributes att) {

         Map imports = parseHeader(att.getValue("Import-Package"));

         Map ver = new TreeMap();

-        ver.put("version", "0.7.5");

+        ver.put("version", "0.7.6");

         if (!imports.containsKey("org.apache.felix.ipojo")) {

             imports.put("org.apache.felix.ipojo", ver);

         }

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
index bea964a..e10e762 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/xml/parser/XMLMetadataParser.java
@@ -38,62 +38,13 @@
     private Element[] m_elements = new Element[0];

 

     /**

-     * Get component type metadata. (both component and composite)

-     * 

-     * @return a components metadata

-     * @throws ParseException :  occurs in the xml parsing

-     */

-    public Element[] getComponentsMetadata() throws ParseException {

-        Element[] comp = m_elements[0].getElements("Component");

-        Element[] compo = m_elements[0].getElements("Composite");

-        Element[] handl = m_elements[0].getElements("Handler");

-        Element[] metadata = new Element[comp.length + compo.length + handl.length];

-        int l = 0;

-        for (int i = 0; i < comp.length; i++) {

-            metadata[l] = comp[i];

-            l++;

-        }

-        for (int i = 0; i < compo.length; i++) {

-            metadata[l] = compo[i];

-            l++;

-        }

-        for (int i = 0; i < handl.length; i++) {

-            metadata[l] = handl[i];

-            l++;

-        }

-        return metadata;

-    }

-

-    /**

      * Get parsed metadata.

      * The document must be parsed before calling this method. 

      * @return : all the metadata.

      * @throws ParseException : occurs if an error occurs during the parsing.

      */

     public Element[] getMetadata() throws ParseException {

-        Element[] comp = m_elements[0].getElements("Component");

-        Element[] compo = m_elements[0].getElements("Composite");

-        Element[] conf = m_elements[0].getElements("Instance");

-        Element[] handl = m_elements[0].getElements("Handler");

-        Element[] metadata = new Element[comp.length + conf.length + compo.length + handl.length];

-        int l = 0;

-        for (int i = 0; i < comp.length; i++) {

-            metadata[l] = comp[i];

-            l++;

-        }

-        for (int i = 0; i < compo.length; i++) {

-            metadata[l] = compo[i];

-            l++;

-        }

-        for (int i = 0; i < conf.length; i++) {

-            metadata[l] = conf[i];

-            l++;

-        }

-        for (int i = 0; i < handl.length; i++) {

-            metadata[l] = handl[i];

-            l++;

-        }

-        return metadata;

+        return m_elements[0].getElements();

     }

 

 

diff --git a/ipojo/metadata/pom.xml b/ipojo/metadata/pom.xml
index 16d2048..38bc6e7 100644
--- a/ipojo/metadata/pom.xml
+++ b/ipojo/metadata/pom.xml
@@ -1,49 +1,52 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
 -->
 <project>
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix</artifactId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-  <packaging>bundle</packaging>
-  <version>0.7.5-SNAPSHOT</version>
-  <name>Apache Felix iPOJO Metadata</name>
-  <build>
-  <plugins>
-  	<plugin>
-    	<groupId>org.apache.felix</groupId>
-    	<artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.0</version>
-    	<extensions>true</extensions>
-    	<configuration>
-        	<instructions>          
-          		<Bundle-Name>iPOJO Metadata</Bundle-Name>
-		        <Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
-        		<Bundle-Description> iPOJO Metadata </Bundle-Description>
-          		<Export-Package>org.apache.felix.ipojo.metadata</Export-Package>
-        	</instructions>
-    	</configuration>
-  	</plugin>
-  </plugins>
-  </build>
+	<parent>
+		<artifactId>iPOJO</artifactId>
+		<groupId>org.apache.felix</groupId>
+		<version>0.7.6-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>org.apache.felix.ipojo.metadata</artifactId>
+	<packaging>bundle</packaging>
+	<name>Apache Felix iPOJO Metadata</name>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>1.4.0</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Name>iPOJO Metadata</Bundle-Name>
+						<Bundle-Vendor>Clement ESCOFFIER</Bundle-Vendor>
+						<Bundle-Description>
+							iPOJO Metadata
+						</Bundle-Description>
+						<Export-Package>
+							org.apache.felix.ipojo.metadata
+						</Export-Package>
+					</instructions>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
 </project>
diff --git a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
index 7b59150..f984aa8 100644
--- a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
+++ b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
@@ -83,7 +83,7 @@
                 list.add(v[i]);
             }
         }
-        return (Element[]) list.toArray(new Element[0]);
+        return (Element[]) list.toArray(new Element[list.size()]);
     }
 
     /**
@@ -223,25 +223,21 @@
     /**
      * 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)
+     * @return the resulting element array (null if the search failed)
      */
     public Element[] getElements(String name) {
         Element[] elems = (Element[]) m_elements.get(name.toLowerCase());
-        if (elems == null) {
-            return new Element[0];
-        } else {
-            return elems;
-        }
+        return elems;
     }
 
     /**
      * 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)
+     * @return the resulting element array (null if the search failed)
      */
     public Element[] getElements(String name, String ns) {
-        if (ns == null || ns.equals("")) {
+        if (ns == null || ns.length() == 0) {
             return getElements(name);
         }
         name = ns + ":" + name;
@@ -254,8 +250,7 @@
      * @return true if the element contains an element of the type "name"
      */
     public boolean containsElement(String name) {
-        name = name.toLowerCase();
-        return m_elements.containsKey(name);
+        return m_elements.containsKey(name.toLowerCase());
     }
 
     /**
@@ -265,7 +260,7 @@
      * @return true if the element contains an element of the type "name"
      */
     public boolean containsElement(String name, String ns) {
-        if (ns != null && !ns.equals("")) {
+        if (ns != null && ns.length() != 0) {
             name = ns + ":" + name;
         }
         return containsElement(name);
diff --git a/ipojo/plugin/pom.xml b/ipojo/plugin/pom.xml
index 39e44c6..3f5c569 100644
--- a/ipojo/plugin/pom.xml
+++ b/ipojo/plugin/pom.xml
@@ -1,68 +1,68 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
 -->
 <project>
-  <parent>
-    <artifactId>felix</artifactId>
-    <groupId>org.apache.felix</groupId>
-    <version>1.0.2</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <artifactId>maven-ipojo-plugin</artifactId>
-  <version>0.7.5-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>xerces</groupId>
-      <artifactId>xercesImpl</artifactId>
-      <version>2.4.0</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>${pom.groupId}</groupId>
-      <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
-      <version>0.7.5-SNAPSHOT</version>
-    </dependency>
-  </dependencies>
+	<parent>
+		<artifactId>iPOJO</artifactId>
+		<groupId>org.apache.felix</groupId>
+		<version>0.7.6-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>maven-ipojo-plugin</artifactId>
+	<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>
+			<scope>compile</scope>
+		</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>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>
+		<dependency>
+			<groupId>${pom.groupId}</groupId>
+			<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+			<version>${pom.version}</version>
+		</dependency>
+	</dependencies>
 </project>
diff --git a/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java b/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
index 474eb75..a7391e1 100644
--- a/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
+++ b/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
@@ -1,4 +1,4 @@
-/*

+/* 

  * Licensed to the Apache Software Foundation (ASF) under one

  * or more contributor license agreements.  See the NOTICE file

  * distributed with this work for additional information

@@ -25,7 +25,6 @@
 import org.apache.felix.ipojo.manipulator.Pojoization;

 import org.apache.maven.plugin.AbstractMojo;

 import org.apache.maven.plugin.MojoExecutionException;

-import org.apache.maven.plugin.MojoFailureException;

 import org.apache.maven.project.MavenProject;

 import org.apache.maven.project.MavenProjectHelper;

 

@@ -113,11 +112,10 @@
 

     /**

      * Execute method : launch the pojoization.

-     * @throws MojoExecutionException : an exception occurs.

-     * @throws MojoFailureException : an failure occurs.

+     * @throws MojoExecutionException : an exception occurs during the manipulation.

      * @see org.apache.maven.plugin.AbstractMojo#execute()

      */

-    public void execute() throws MojoExecutionException, MojoFailureException {

+    public void execute() throws MojoExecutionException {

         // ignore project types not supported, useful when the plugin is configured in the parent pom

         if (!this.m_supportedProjectTypes.contains(this.getProject().getArtifact().getType())) {

             this.getLog().debug("Ignoring project " + this.getProject().getArtifact() + " : type " + this.getProject().getArtifact().getType() + " is not supported by ipojo plugin, supported types are " + this.m_supportedProjectTypes);

@@ -126,7 +124,15 @@
 

         getLog().info("Start bundle manipulation");

         // Get metadata file

+        

+        // Look for the metadata file in the output directory

         File meta = new File(m_outputDirectory + File.separator + m_metadata);

+        

+        // If not found look inside the pom directory

+        if (! meta.exists()) {

+            meta = new File(m_project.getBasedir() + File.separator + m_metadata);

+        }

+        

         getLog().info("Metadata File : " + meta.getAbsolutePath());

         if (!meta.exists()) {

             // Verify if annotations are ignored

diff --git a/ipojo/plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml b/ipojo/plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
index a3d0839..cccd90d 100644
--- a/ipojo/plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
+++ b/ipojo/plugin/src/main/resources/archetype-resources/src/main/resources/metadata.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<iPOJO>
-	<component className="$YOUR_COMPONENT_CLASS">
-   
-	</component>
-	<instance component="$YOUR_COMPONENT_CLASS"/>
+<?xml version="1.0" encoding="UTF-8"?>

+<iPOJO>

+	<component className="$YOUR_COMPONENT_CLASS">

+   

+	</component>

+	<instance component="$YOUR_COMPONENT_CLASS"/>

 </iPOJO>
\ No newline at end of file
diff --git a/ipojo/pom.xml b/ipojo/pom.xml
index 901c80c..d1a1378 100644
--- a/ipojo/pom.xml
+++ b/ipojo/pom.xml
@@ -19,22 +19,63 @@
 <project>

   <parent>

     <groupId>org.apache.felix</groupId>

-    <artifactId>felix</artifactId>

+    <artifactId>felix</artifactId>
     <version>1.0.2</version>
-    <relativePath>../pom/pom.xml</relativePath>

+    <relativePath>../pom/pom.xml</relativePath>
   </parent>

 

   <modelVersion>4.0.0</modelVersion>

-  <artifactId>ipojo</artifactId>

+  <artifactId>iPOJO</artifactId>

+  <groupId>org.apache.felix</groupId>

   <name>Apache Felix iPOJO</name>

-  <version>0.7.5-SNAPSHOT</version>

+  <version>0.7.6-SNAPSHOT</version>

   <packaging>pom</packaging>

-  <modules>

-	<module>metadata</module>

-    <module>manipulator</module>

-	<module>plugin</module>

-    <module>core</module>

-    <module>arch</module>

-	<module>ant</module>

-  </modules>

-</project>
\ No newline at end of file
+  

+  	<modules>

+		<module>metadata</module>

+		<module>manipulator</module>

+		<module>plugin</module>

+		<module>core</module>

+		<module>composite</module>

+		<module>arch</module>

+		<module>ant</module>

+		<module>event.admin.handler</module>

+		<module>white.board.pattern.handler</module>

+		<module>extender.pattern.handler</module>

+	</modules>

+	

+  <profiles>

+	<profile>

+		<id>java5</id>

+		<activation>

+			<jdk>1.5</jdk>

+		</activation>

+		<modules>

+			<module>annotations</module>

+			<module>jmx.handler</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>java6</id>

+		<activation>

+			<jdk>1.6</jdk>

+		</activation>

+		<modules>

+			<module>annotations</module>

+			<module>jmx.handler</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>examples</id>

+		<modules>

+			<module>examples</module>

+		</modules>

+	</profile>

+	<profile>

+		<id>tests</id>

+		<modules>

+			<module>tests</module>

+		</modules>

+	</profile>

+  </profiles>
+</project>
diff --git a/ipojo/tests/pom.xml b/ipojo/tests/pom.xml
new file mode 100644
index 0000000..f6c29e5
--- /dev/null
+++ b/ipojo/tests/pom.xml
@@ -0,0 +1,36 @@
+<project>

+  <parent>

+    <groupId>org.apache.felix</groupId>

+    <artifactId>iPOJO</artifactId>

+    <version>0.7.6-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+

+  <modelVersion>4.0.0</modelVersion>

+  <groupId>ipojo.tests</groupId>

+  <artifactId>ipojo.tests</artifactId>

+  <name>Apache Felix iPOJO Tests</name>

+  <packaging>pom</packaging>

+  <profiles>

+      <profile>

+              <id>java5</id>

+              <activation>

+                      <jdk>1.5</jdk>

+              </activation>

+              <modules>

+                     <module>tests.core</module>

+					<module>tests.composite</module>

+              </modules>

+      </profile>

+      <profile>

+              <id>java6</id>

+              <activation>

+                      <jdk>1.6</jdk>

+              </activation>

+              <modules>

+                      <module>tests.core</module>

+					  <module>tests.composite</module>

+              </modules>

+      </profile>

+</profiles>  

+</project>
\ No newline at end of file
diff --git a/ipojo/tests/tests.composite/pom.xml b/ipojo/tests/tests.composite/pom.xml
new file mode 100644
index 0000000..e016d37
--- /dev/null
+++ b/ipojo/tests/tests.composite/pom.xml
@@ -0,0 +1,112 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.tests</groupId>

+		<artifactId>ipojo.tests</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>iPOJO Composite Test Suite</name>

+	<artifactId>tests.composite</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.composite</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>ipojo.tests</groupId>

+			<artifactId>tests.core</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Export-Package>

+							org.apache.felix.ipojo.test.composite.service

+						</Export-Package>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.test.composite.*

+						</Private-Package>

+						<Test-Suite>

+							org.apache.felix.ipojo.test.composite.CompositeTestSuite

+						</Test-Suite>

+						<Import-Package>

+							org.apache.felix.ipojo.test.scenarios.service,*

+						</Import-Package>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>0.7.6-SNAPSHOT</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/CompositeTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/CompositeTestSuite.java
new file mode 100644
index 0000000..efa9de3
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/CompositeTestSuite.java
@@ -0,0 +1,48 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.apache.felix.ipojo.test.composite.exporter.ExportTestSuite;

+import org.apache.felix.ipojo.test.composite.importer.ImportTestSuite;

+import org.apache.felix.ipojo.test.composite.infrastructure.InfrastructureTestSuite;

+import org.apache.felix.ipojo.test.composite.instance.SimpleInstance;

+import org.apache.felix.ipojo.test.composite.instantiator.InstantiatorTestSuite;

+import org.apache.felix.ipojo.test.composite.provides.ProvidesTestSuite;

+import org.apache.felix.ipojo.test.composite.test.CompositeTest;

+import org.osgi.framework.BundleContext;

+

+public class CompositeTestSuite {

+    

+    public static Test suite(BundleContext bc) {

+        OSGiTestSuite ots = new OSGiTestSuite("iPOJO Composites Test Suite", bc);    

+        ots.addTest(InfrastructureTestSuite.suite(bc));

+        ots.addTest(InstantiatorTestSuite.suite(bc));

+        ots.addTest(ImportTestSuite.suite(bc));

+        ots.addTest(ExportTestSuite.suite(bc));

+        ots.addTestSuite(CompositeTest.class);

+        ots.addTestSuite(SimpleInstance.class);

+        ots.addTest(ProvidesTestSuite.suite(bc));

+

+        return ots;

+    }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/Baz2CheckProvider.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/Baz2CheckProvider.java
new file mode 100644
index 0000000..662c8e2
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/Baz2CheckProvider.java
@@ -0,0 +1,81 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class Baz2CheckProvider implements CheckService {

+	

+	BazService fs;

+	

+	int simpleB = 0;

+	int objectB = 0;

+	int refB = 0;

+	int simpleU = 0;

+	int objectU = 0;

+	int refU = 0;

+

+	public boolean check() {

+		return fs.foo();

+	}

+

+	public Properties getProps() {

+		Properties props = new Properties();

+		props.put("result", new Boolean(fs.foo()));

+		props.put("voidB", new Integer(simpleB));

+		props.put("objectB", new Integer(objectB));

+		props.put("refB", new Integer(refB));

+		props.put("voidU", new Integer(simpleU));

+		props.put("objectU", new Integer(objectU));

+		props.put("refU", new Integer(refU));

+		props.put("boolean", new Boolean(fs.getBoolean()));

+		props.put("int", new Integer(fs.getInt()));

+		props.put("long", new Long(fs.getLong()));

+		props.put("double", new Double(fs.getDouble()));

+		if(fs.getObject() != null) { props.put("object", fs.getObject()); }

+		

+		return props;

+	}

+	

+	private void voidBind() {

+		simpleB++;

+	}

+	private void voidUnbind() {

+		simpleU++;

+	}

+	

+	protected void objectBind(Object o) {

+		if(o != null && o instanceof FooService) { objectB++; }

+	}

+	protected void objectUnbind(Object o) {

+		if(o != null && o instanceof FooService) { objectU++; }

+	}

+	

+	public void refBind(ServiceReference sr) {

+		if(sr != null) { refB++; }

+	}

+	public void refUnbind(ServiceReference sr) {

+		if(sr != null) { refU++; }

+	}

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/BazProviderType1.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/BazProviderType1.java
new file mode 100644
index 0000000..6917d39
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/BazProviderType1.java
@@ -0,0 +1,51 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+

+public class BazProviderType1 implements BazService {

+	

+	private int m_bar;

+	private String m_foo;

+

+	public boolean foo() {

+		return true;

+	}

+

+	public Properties fooProps() {

+		Properties p = new Properties();

+		p.put("bar", new Integer(m_bar));

+		p.put("foo", m_foo);

+		return p;

+	}

+	

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TataProvider.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TataProvider.java
new file mode 100644
index 0000000..2607b55
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TataProvider.java
@@ -0,0 +1,222 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.composite.service.Tata;

+

+

+public class TataProvider implements Tata {

+    

+    int tata = 0;

+    int tataStr = 0;

+    int tataStrs = 0;

+    int tata_2 = 0;

+    int tata_3 = 0;

+    int tata1 = 0;

+    int tata1_1 = 0;

+    int tata5 = 0;

+    int tata5_1 = 0;

+    int tata5_2 = 0;

+    int tataBoolean = 0;

+    int tataBooleans = 0;

+    int tataByte = 0;

+    int tataBytes = 0;

+    private int add;

+    private int tataShorts;

+    private int tataShort;

+    private int tataLongs;

+    private int tataLong;

+    private int tataInts;

+    private int tataInt;

+    private int tataFloat;

+    private int tataFloats;

+    private int tataDoubles;

+    private int tataDouble;

+    private int tataChars;

+    private int tataChar;

+    

+    public Properties getPropsTata() {

+        Properties props = new Properties();

+        props.put("tata", new Integer(tata));

+        props.put("tataStr", new Integer(tataStr));

+        props.put("tataStrs", new Integer(tataStrs));

+        props.put("tata_2", new Integer(tata_2));

+        props.put("tata_3", new Integer(tata_3));

+        props.put("tata1", new Integer(tata1));

+        props.put("tata1_1", new Integer(tata1_1));

+        props.put("tata5", new Integer(tata5));

+        props.put("tata5_1", new Integer(tata5_1));

+        props.put("tata5_2", new Integer(tata5_2));

+        props.put("add", new Integer(add));

+        props.put("tataBoolean", new Integer(tataBoolean));

+        props.put("tataBoolean", new Integer(tataBoolean));

+        props.put("tataByte", new Integer(tataByte));

+        props.put("tataBytes", new Integer(tataBytes));

+        props.put("tataShort", new Integer(tataShort));

+        props.put("tataShorts", new Integer(tataShorts));

+        props.put("tataLongs", new Integer(tataLongs));

+        props.put("tataLong", new Integer(tataLong));

+        props.put("tataInt", new Integer(tataInt));

+        props.put("tataInts", new Integer(tataInts));

+        props.put("tataFloat", new Integer(tataFloat));

+        props.put("tataFloats", new Integer(tataFloats));

+        props.put("tataDouble", new Integer(tataDouble));

+        props.put("tataDoubles", new Integer(tataDoubles));

+        props.put("tataChar", new Integer(tataChar));

+        props.put("tataChars", new Integer(tataChars));

+        return props;

+    }

+

+    public void tata() {

+        tata++;

+    }

+

+    public String tataStr() {

+        tataStr++;

+        return "Tata";

+    }

+

+    public String[] tataStrs() {

+        tataStrs++;

+        return new String[] {"T", "A", "T", "A"};

+    }

+

+    public void tata(int i, int j) {

+        tata_2++;        

+    }

+

+    public void tata(String s) {

+        tata_3++;

+    }

+

+    public String tata1(String a) {

+        tata1++;

+       return a;

+    }

+

+    public String tata1(char[] a) {

+        tata1_1++;

+        String s = new String(a);

+        return s;

+    }

+

+    public String tata5(String a, int i) {

+       tata5++;

+       return a+i;

+    }

+

+    public String tata5(String[] a, int i) {

+       tata5_1++;

+       return ""+a.length + i;

+    }

+

+    public String tata5(String a, int[] i) {

+        tata5_2++;

+        return a + i.length;

+    }

+

+    public boolean tataBoolean(boolean b) {

+        tataBoolean++;

+        return b;

+    }

+

+    public boolean[] tataBooleans(boolean[] b) {

+        tataBooleans++;

+       return b;

+    }

+

+    public byte tataByte(byte b) {

+        tataByte++;

+        return b;

+    }

+

+    public byte[] tataBytes(byte[] b) {

+        tataBytes++;

+        return b;

+    }

+

+    public char tataChar(char c) {

+       tataChar++;

+       return c;

+    }

+

+    public char[] tataChars(char[] c) {

+        tataChars++;

+        return c;

+    }

+

+    public double tataDouble(double d) {

+        tataDouble++;

+        return d;

+    }

+

+    public double[] tataDoubles(double[] d) {

+        tataDoubles++;

+        return d;

+    }

+

+    public float tataFloat(float f) {

+        tataFloat++;

+        return f;

+    }

+

+    public float[] tataFloats(float[] f) {

+        tataFloats++;

+        return f;

+    }

+

+    public int tataInt(int i) {

+        tataInt++;

+        return i;

+    }

+

+    public int[] tataInts(int[] its) {

+        tataInts++;

+        return its;

+    }

+

+    public long tataLong(long l) {

+        tataLong++;

+        return l;

+    }

+

+    public long[] tataLongs(long[] l) {

+        tataLongs++;

+        return l;

+    }

+

+    public short tataShort(short s) {

+        tataShort++;

+        return s;

+    }

+

+    public short[] tataShorts(short[] s) {

+        tataShorts++;

+        return s;

+    }

+

+    public long add(int i, int j, int k) {

+        add++;

+        return i + j + k;

+    }

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProvider.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProvider.java
new file mode 100644
index 0000000..fb79bc4
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProvider.java
@@ -0,0 +1,73 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.composite.service.Toto;

+

+

+public class TotoProvider implements Toto {

+    

+    private int i = 0;

+    public static int toto = 0;

+    public static int toto_2 = 0;

+    public static int toto_3 = 0;

+    public static int toto_4 = 0;

+    public static int toto1 = 0;

+    

+    public int count() {

+        return i;

+    }

+    

+    public void toto() {

+        toto++;        

+    }

+

+    public void toto(int i, int j) {

+        toto_2++;

+    }

+

+    public String toto(String a) {

+        toto_3++;

+        return a;

+    }

+

+    public String toto(String[] a) {

+        toto_4++;

+        return "toto";

+    }

+

+    public void toto1(String j) {

+        i++;

+        toto1++;        

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("i", new Integer(i));

+        props.put("toto", new Integer(toto));

+        props.put("toto_2", new Integer(toto_2));

+        props.put("toto_3", new Integer(toto_3));

+        props.put("toto_4", new Integer(toto_4));

+        props.put("toto1", new Integer(toto1));

+        return props;

+    }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProviderGlue.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProviderGlue.java
new file mode 100644
index 0000000..3ea3a88
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/component/TotoProviderGlue.java
@@ -0,0 +1,81 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.composite.service.Toto;

+

+

+public class TotoProviderGlue implements Toto {

+    

+    Toto m_toto;

+    

+    private int i = 0;

+    public static int toto = 0;

+    public static int toto_2 = 0;

+    public static int toto_3 = 0;

+    public static int toto_4 = 0;

+    public static int toto1 = 0;

+    

+    public int count() {

+        return i;

+    }

+    

+    public void toto() {

+        toto++;

+        m_toto.toto();

+    }

+

+    public void toto(int i, int j) {

+        toto_2++;

+        m_toto.toto(i, j);

+    }

+

+    public String toto(String a) {

+        toto_3++;

+        return a;

+    }

+

+    public String toto(String[] a) {

+        toto_4++;

+        return "toto";

+    }

+

+    public void toto1(String j) {

+        i++;

+        toto1++;

+        m_toto.toto1(j);

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("i", new Integer(i));

+        props.put("gtoto", new Integer(toto));

+        props.put("gtoto_2", new Integer(toto_2));

+        props.put("gtoto_3", new Integer(toto_3));

+        props.put("gtoto_4", new Integer(toto_4));

+        props.put("gtoto1", new Integer(toto1));

+        props.put("glue", "glue");

+        Properties p2 = m_toto.getProps();

+        props.putAll(p2);

+        return props;

+    }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/ExportTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/ExportTestSuite.java
new file mode 100644
index 0000000..d9b84f1
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/ExportTestSuite.java
@@ -0,0 +1,40 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ExportTestSuite extends TestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Composite Service Exporters Test Suite", bc);

+		ots.addTestSuite(SimpleExport.class);

+		ots.addTestSuite(OptionalExport.class);

+		ots.addTestSuite(MultipleExport.class);

+		ots.addTestSuite(OptionalMultipleExport.class);

+		ots.addTestSuite(FilteredExport.class);

+		ots.setBundleContext(bc);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/FilteredExport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/FilteredExport.java
new file mode 100644
index 0000000..938bb94
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/FilteredExport.java
@@ -0,0 +1,230 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class FilteredExport extends OSGiTestCase {

+	

+	ComponentInstance export1;

+	Factory fooProvider;

+	ComponentInstance foo1 = null, foo2 = null;

+	

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "BazProviderType");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to create foos : " + e.getMessage());

+		}

+		

+		foo1.stop();

+		foo2.stop();

+		

+		Factory factory = Utils.getFactoryByName(context, "composite.export.5");

+		Properties props = new Properties();

+		props.put("name", "export");

+		try {

+			export1 = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Fail to instantiate exporter " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		export1.dispose();

+		foo1 = null;

+		foo2 = null;

+		export1 = null;

+	}

+	

+	public void test1() {

+		export1.start();

+		

+		// Check that no foo service are available

+		assertEquals("Check no foo service", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 0);

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 3", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 4", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check invalidity - 5", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 0);

+	}

+	

+	public void test2() {

+		export1.start();

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 4", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 5", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke());

+	}

+	

+	public void test3() {

+		foo1.start();

+		foo2.start();

+		

+		export1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 2", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 0);

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 3", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 4", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke());

+	}

+	

+	public void test4() {

+		foo1.start();

+		foo2.start();

+		

+		export1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 3", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check invalidity - 4", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+	}

+	

+	

+	

+	private boolean isFooServiceProvided() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export1.getInstanceName());

+		return ref != null;

+	}

+	

+	private int countFooServiceProvided() {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export1.getInstanceName()+")");

+		return refs.length;

+	}

+	

+	private boolean invoke() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export1.getInstanceName());

+		if(ref == null) { return false; }

+		BazService fs = (BazService) context.getService(ref);

+		return fs.foo();

+	}

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/MultipleExport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/MultipleExport.java
new file mode 100644
index 0000000..10a0a4e
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/MultipleExport.java
@@ -0,0 +1,247 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleExport extends OSGiTestCase {

+	

+	ComponentInstance export3;

+	Factory fooProvider;

+	ComponentInstance foo1 = null, foo2 = null;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "BazProviderType");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to create foos : " + e.getMessage());

+		}

+		

+		foo1.stop();

+		foo2.stop();

+		

+		Factory factory = Utils.getFactoryByName(context, "composite.export.3");

+		Properties props = new Properties();

+		props.put("name", "export");

+		try {

+			export3 = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Fail to instantiate exporter " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		export3.dispose();

+		foo1 = null;

+		foo2 = null;

+		export3 = null;

+	}

+	

+	public void test1() {

+		export3.start();

+		

+		// Check that no foo service are available

+		assertEquals("Check no foo service", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 0);

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke(1));

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 2", invoke(2));

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3 ("+countFooServiceProvided()+")", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke(1));

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 4", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 5", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke(1));

+	}

+	

+	public void test2() {

+		export3.start();

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 2", invoke(2));

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke(1));

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 4", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 5", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke(1));

+	}

+	

+	public void test3() {

+		foo1.start();

+		foo2.start();

+		

+		export3.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 1", invoke(2));

+		

+		foo1.stop();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke(1));

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 3", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke(1));

+	}

+	

+	public void test4() {

+		foo1.start();

+		foo2.start();

+		

+		export3.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 1", invoke(2));

+		

+		foo2.stop();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke(1));

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 3", export3.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke(1));

+	}

+	

+	

+	

+	private boolean isFooServiceProvided() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export3.getInstanceName());

+		return ref != null;

+	}

+	

+	private int countFooServiceProvided() {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export3.getInstanceName()+")");

+		return refs.length;

+	}

+	

+	private boolean invoke() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export3.getInstanceName());

+		if(ref == null) { return false; }

+		BazService fs = (BazService) context.getService(ref);

+		context.ungetService(ref);

+		return fs.foo();

+	}

+	

+	private boolean invoke(int nb) {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export3.getInstanceName()+")");

+		if(refs == null) { return false; }

+		if (nb > refs.length) { return false; }

+		for(int i = 0; i < nb; i++) {

+			BazService fs = (BazService) context.getService(refs[i]);

+			context.ungetService(refs[i]);

+			if(!fs.foo()) { return false; }

+		}

+		return true;

+	}

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalExport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalExport.java
new file mode 100644
index 0000000..5c30d24
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalExport.java
@@ -0,0 +1,234 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalExport extends OSGiTestCase {

+	

+	ComponentInstance export2;

+	Factory fooProvider;

+	ComponentInstance foo1 = null, foo2 = null;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "BazProviderType");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to create foos : " + e.getMessage());

+		}

+		

+		foo1.stop();

+		foo2.stop();

+		

+		Factory factory = Utils.getFactoryByName(context, "composite.export.2");

+		Properties props = new Properties();

+		props.put("name", "export");

+		try {

+			export2 = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Fail to instantiate exporter " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		export2.dispose();

+		foo1 = null;

+		foo2 = null;

+		export2 = null;

+	}

+	

+	public void test1() {

+		export2.start();

+		

+		// Check that no foo service are available

+		assertEquals("Check no foo service", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 0);

+		

+		// Test validity

+		assertTrue("Check validity - 0", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3 ("+countFooServiceProvided()+")", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 4", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 5", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke());

+	}

+	

+	public void test2() {

+		export2.start();

+		

+		// Test invalidity

+		assertTrue("Check validity - 0", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 4", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 5", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke());

+	}

+	

+	public void test3() {

+		foo1.start();

+		foo2.start();

+		

+		export2.start();

+		assertTrue("Check validity - 1", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 2", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 4", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke());

+	}

+	

+	public void test4() {

+		foo1.start();

+		foo2.start();

+		

+		export2.start();

+		assertTrue("Check validity - 1", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 2", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export2.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 4", export2.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke());

+	}

+	

+	

+	

+	private boolean isFooServiceProvided() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export2.getInstanceName());

+		return ref != null;

+	}

+	

+	private int countFooServiceProvided() {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export2.getInstanceName()+")");

+		return refs.length;

+	}

+	

+	private boolean invoke() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export2.getInstanceName());

+		if(ref == null) { return false; }

+		BazService fs = (BazService) context.getService(ref);

+		return fs.foo();

+	}

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalMultipleExport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalMultipleExport.java
new file mode 100644
index 0000000..997be4e
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/OptionalMultipleExport.java
@@ -0,0 +1,247 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalMultipleExport extends OSGiTestCase {

+	

+	ComponentInstance export3;

+	Factory fooProvider;

+	ComponentInstance foo1 = null, foo2 = null;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "BazProviderType");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to create foos : " + e.getMessage());

+		}

+		

+		foo1.stop();

+		foo2.stop();

+		

+		Factory factory = Utils.getFactoryByName(context, "composite.export.4");

+		Properties props = new Properties();

+		props.put("name", "export");

+		try {

+			export3 = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Fail to instantiate exporter " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		export3.dispose();

+		foo1 = null;

+		foo2 = null;

+		export3 = null;

+	}

+	

+	public void test1() {

+		export3.start();

+		

+		// Check that no foo service are available

+		assertEquals("Check no foo service", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 0);

+		

+		// Test invalidity

+		assertTrue("Check validity - 0", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke(1));

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 2", invoke(2));

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3 ("+countFooServiceProvided()+")", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke(1));

+		

+		foo2.stop();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 5", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke(1));

+	}

+	

+	public void test2() {

+		export3.start();

+		

+		// Test invalidity

+		assertTrue("Check validity - 0", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 2", invoke(2));

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke(1));

+		

+		foo1.stop();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 5", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke(1));

+	}

+	

+	public void test3() {

+		foo1.start();

+		foo2.start();

+		

+		export3.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 1", invoke(2));

+		

+		foo1.stop();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke(1));

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke(1));

+	}

+	

+	public void test4() {

+		foo1.start();

+		foo2.start();

+		

+		export3.start();

+		assertTrue("Check validity - 1", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 2);

+		assertTrue("Check invocation - 1", invoke(2));

+		

+		foo2.stop();

+		assertTrue("Check validity - 2", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke(1));

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export3.getState() == ComponentInstance.VALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 4", export3.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke(1));

+	}

+	

+	

+	

+	private boolean isFooServiceProvided() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export3.getInstanceName());

+		return ref != null;

+	}

+	

+	private int countFooServiceProvided() {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export3.getInstanceName()+")");

+		return refs.length;

+	}

+	

+	private boolean invoke() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export3.getInstanceName());

+		if(ref == null) { return false; }

+		BazService fs = (BazService) context.getService(ref);

+		context.ungetService(ref);

+		return fs.foo();

+	}

+	

+	private boolean invoke(int nb) {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export3.getInstanceName()+")");

+		if(refs == null) { return false; }

+		if (nb > refs.length) { return false; }

+		for(int i = 0; i < nb; i++) {

+			BazService fs = (BazService) context.getService(refs[i]);

+			context.ungetService(refs[i]);

+			if(!fs.foo()) { return false; }

+		}

+		return true;

+	}

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/SimpleExport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/SimpleExport.java
new file mode 100644
index 0000000..5ee7cd7
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/exporter/SimpleExport.java
@@ -0,0 +1,234 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.exporter;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleExport extends OSGiTestCase {

+	

+	ComponentInstance export1;

+	Factory fooProvider;

+	ComponentInstance foo1 = null, foo2 = null;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "BazProviderType");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to create foos : " + e.getMessage());

+		}

+		

+		foo1.stop();

+		foo2.stop();

+		

+		Factory factory = Utils.getFactoryByName(context, "composite.export.1");

+		Properties props = new Properties();

+		props.put("name", "export");

+		try {

+			export1 = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Fail to instantiate exporter " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		export1.dispose();

+		foo1 = null;

+		foo2 = null;

+		export1 = null;

+	}

+	

+	public void test1() {

+		export1.start();

+		

+		// Check that no foo service are available

+		assertEquals("Check no foo service", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 0);

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 3", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3 ("+countFooServiceProvided()+")", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke());

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 4", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 5", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke());

+	}

+	

+	public void test2() {

+		export1.start();

+		

+		// Test invalidity

+		assertTrue("Check invalidity - 0", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 0", isFooServiceProvided());

+		assertEquals("Check number of provides - 0", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.start();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 3", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 3", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 4", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 5", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 5", isFooServiceProvided());

+		assertEquals("Check number of provides - 5", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 5", invoke());

+	}

+	

+	public void test3() {

+		foo1.start();

+		foo2.start();

+		

+		export1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo1.stop();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo2.stop();

+		assertTrue("Check invalidity - 3", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo1.start();

+		assertTrue("Check validity - 4", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke());

+	}

+	

+	public void test4() {

+		foo1.start();

+		foo2.start();

+		

+		export1.start();

+		assertTrue("Check validity - 1", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 1", isFooServiceProvided());

+		assertEquals("Check number of provides - 1", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 1", invoke());

+		

+		foo2.stop();

+		assertTrue("Check validity - 2", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 2", isFooServiceProvided());

+		assertEquals("Check number of provides - 2", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 2", invoke());

+		

+		foo1.stop();

+		assertTrue("Check invalidity - 3", export1.getState() == ComponentInstance.INVALID);

+		assertFalse("Check providing - 3", isFooServiceProvided());

+		assertEquals("Check number of provides - 3", countFooServiceProvided(), 0);

+		

+		foo2.start();

+		assertTrue("Check validity - 4", export1.getState() == ComponentInstance.VALID);

+		assertTrue("Check providing - 4", isFooServiceProvided());

+		assertEquals("Check number of provides - 4", countFooServiceProvided(), 1);

+		assertTrue("Check invocation - 4", invoke());

+	}

+	

+	

+	

+	private boolean isFooServiceProvided() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export1.getInstanceName());

+		return ref != null;

+	}

+	

+	private int countFooServiceProvided() {

+		ServiceReference[] refs = Utils.getServiceReferences(context, BazService.class.getName(), "(instance.name="+export1.getInstanceName()+")");

+		return refs.length;

+	}

+	

+	private boolean invoke() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), export1.getInstanceName());

+		if(ref == null) { return false; }

+		BazService fs = (BazService) context.getService(ref);

+		return fs.foo();

+	}

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedFilteredImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedFilteredImport.java
new file mode 100644
index 0000000..659705f
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedFilteredImport.java
@@ -0,0 +1,150 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedFilteredImport extends OSGiTestCase {

+	

+	ComponentInstance import1;

+	Factory fooProvider;

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.1");

+		try {

+			import1 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		

+		import1.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import1.dispose();

+		foo1 = null;

+		foo2 = null;

+		import1 = null;

+	}

+	

+	public void testSimple() {

+		import1.start(); 

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo2.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import1.start(); 

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo2.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedMultipleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedMultipleImport.java
new file mode 100644
index 0000000..99b359c
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedMultipleImport.java
@@ -0,0 +1,156 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedMultipleImport extends OSGiTestCase {

+	

+	ComponentInstance import2;

+	Factory fooProvider;

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.2");

+		try {

+			import2 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		

+		import2.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import2.dispose();

+		foo1 = null;

+		foo2 = null;

+		import2 = null;

+	}

+	

+	public void testSimple() {

+		import2.start(); 

+		//Two providers

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		fs = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation (2)", fs.foo());

+		sc.ungetService(refs[1]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component invalidity - 2", import2.getState() == ComponentInstance.INVALID);

+		

+		foo2.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import2.start(); 

+		//Two providers

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		fs = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[1]);

+		

+		foo2.stop();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component invalidity - 2", import2.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalImport.java
new file mode 100644
index 0000000..41ffb28
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalImport.java
@@ -0,0 +1,156 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedOptionalImport extends OSGiTestCase {

+	

+	ComponentInstance import3;

+	Factory fooProvider;

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.3");

+		try {

+			import3 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		

+		import3.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import3.dispose();

+		foo1 = null;

+		foo2 = null;

+		import3 = null;

+	}

+	

+	public void testSimple() {

+		import3.start(); 

+		//Two providers

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import3);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component validity - 2", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo non-availability inside the composite - 3.1", refs.length, 0);

+		

+		foo2.start();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import3.start(); 

+		//Two providers

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import3);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo2.stop();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component validity - 2", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 0);

+		

+		foo1.start();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalMultipleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalMultipleImport.java
new file mode 100644
index 0000000..de9d875
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedOptionalMultipleImport.java
@@ -0,0 +1,162 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedOptionalMultipleImport extends OSGiTestCase {

+	

+	ComponentInstance import4;

+	Factory fooProvider;

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.4");

+		try {

+			import4 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		

+		import4.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import4.dispose();

+		foo1 = null;

+		foo2 = null;

+		import4 = null;

+	}

+	

+	public void testSimple() {

+		import4.start(); 

+		//Two providers

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import4);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		fs = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation (2)", fs.foo());

+		sc.ungetService(refs[1]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component validity - 2", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo availability inside the composite - 1", refs.length, 0);

+		

+		foo2.start();

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import4.start(); 

+		//Two providers

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import4);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		fs = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[1]);

+		

+		foo2.stop();

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component validity - 2", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo availability inside the composite - 1", refs.length, 0);

+		

+		foo1.start();

+		assertTrue("Test component validity", import4.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import4);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedSimpleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedSimpleImport.java
new file mode 100644
index 0000000..e29055d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/DelayedSimpleImport.java
@@ -0,0 +1,151 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedSimpleImport extends OSGiTestCase {

+	

+	ComponentInstance import1;

+	Factory fooProvider;

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.1");

+		try {

+			import1 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		

+		import1.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import1.dispose();

+		foo1 = null;

+		foo2 = null;

+		import1 = null;

+	}

+	

+	public void testSimple() {

+        import1.start();

+

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo2.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import1.start(); 

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo2.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/FilteredImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/FilteredImport.java
new file mode 100644
index 0000000..69b3a37
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/FilteredImport.java
@@ -0,0 +1,147 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class FilteredImport extends OSGiTestCase {

+	

+	ComponentInstance import1;

+	Factory fooProvider;

+	Factory fooProvider2;

+	

+	ComponentInstance foo1, foo2;

+

+	public void setUp() {

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.5");

+		try {

+			import1 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+		import1.stop();

+		

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-2");

+		assertNotNull("Check fooProvider availability", fooProvider2);

+		

+		Properties p1 = new Properties();

+		p1.put("name", "foo1");

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo1 = fooProvider.createComponentInstance(p1);

+			foo2 = fooProvider2.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		foo1.dispose();

+		foo2.dispose();

+		import1.dispose();

+		foo1 = null;

+		foo2 = null;

+		import1 = null;

+	}

+	

+	public void testSimple() {

+		import1.start(); 

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo2.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}

+	

+	public void testSimple2() {

+		import1.start(); 

+		//Two providers

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo2.stop();

+		assertTrue("Test component invalidity - 1", import1.getState() == ComponentInstance.INVALID);

+		

+		// Stop the second provider

+		foo1.stop();		

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component invalidity - 3", import1.getState() == ComponentInstance.INVALID);

+		

+		foo2.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+	}	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/ImportTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/ImportTestSuite.java
new file mode 100644
index 0000000..2f25b2c
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/ImportTestSuite.java
@@ -0,0 +1,43 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ImportTestSuite {

+

+	public static Test suite(BundleContext bc) {

+	    OSGiTestSuite ots = new OSGiTestSuite("Composite Import Test Suite", bc);

+	    ots.addTestSuite(SimpleImport.class);

+	    ots.addTestSuite(DelayedSimpleImport.class);

+	    ots.addTestSuite(OptionalImport.class);

+	    ots.addTestSuite(DelayedOptionalImport.class);

+	    ots.addTestSuite(MultipleImport.class);

+	    ots.addTestSuite(DelayedMultipleImport.class);

+	    ots.addTestSuite(OptionalMultipleImport.class);

+	    ots.addTestSuite(DelayedOptionalMultipleImport.class);

+	    ots.addTestSuite(FilteredImport.class);

+	    ots.addTestSuite(DelayedFilteredImport.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/MultipleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/MultipleImport.java
new file mode 100644
index 0000000..4d5df53
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/MultipleImport.java
@@ -0,0 +1,190 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleImport extends OSGiTestCase {

+	

+	ComponentInstance import2;

+	Factory fooProvider;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.2");

+		try {

+			import2 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		import2.dispose();

+		import2 = null;

+	}

+	

+	public void testSimple() {

+		// No provider -> Invalid

+		assertTrue("Test component invalidity", import2.getState() == ComponentInstance.INVALID);

+		

+		ComponentInstance foo = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2 ("+refs.length+")", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		FooService fs2 = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs2.foo());

+		sc.ungetService(refs[0]);

+		sc.ungetService(refs[1]);

+		

+		// Stop the second provider

+		foo2.dispose();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the foo provider

+		foo.stop();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import2.getState() == ComponentInstance.INVALID);

+		

+		foo.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import2.getState() == ComponentInstance.INVALID);

+	}

+	

+	public void testSimple2() {

+		// No provider -> Invalid

+		assertTrue("Test component invalidity", import2.getState() == ComponentInstance.INVALID);

+		

+		ComponentInstance foo1 = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo1 = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2 ("+refs.length+")", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		FooService fs2 = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs2.foo());

+		sc.ungetService(refs[0]);

+		sc.ungetService(refs[1]);

+		

+		// Stop the first provider

+		foo1.stop();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the second foo provider

+		foo2.dispose();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import2.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import2.getState() == ComponentInstance.INVALID);

+	}

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalImport.java
new file mode 100644
index 0000000..69cd1bb
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalImport.java
@@ -0,0 +1,184 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalImport extends OSGiTestCase {

+	

+	ComponentInstance import3;

+	Factory fooProvider;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.3");

+		try {

+			import3 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		import3.dispose();

+		import3 = null;

+	}

+	

+	public void testSimple() {

+		// No provider -> valid

+		assertTrue("Test component invalidity", import3.getState() == ComponentInstance.VALID);

+		

+		ComponentInstance foo = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import3);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.dispose();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the foo provider

+		foo.stop();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import3.getState() == ComponentInstance.VALID);

+		

+		foo.start();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import3.getState() == ComponentInstance.VALID);

+	}

+	

+	public void testSimple2() {

+		// No provider -> valid

+		assertTrue("Test component invalidity", import3.getState() == ComponentInstance.VALID);

+		

+		ComponentInstance foo1 = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo1 = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import3);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo1.stop();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the foo provider

+		foo2.dispose();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import3.getState() == ComponentInstance.VALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import3.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import3);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import3.getState() == ComponentInstance.VALID);

+	}

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalMultipleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalMultipleImport.java
new file mode 100644
index 0000000..811301d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/OptionalMultipleImport.java
@@ -0,0 +1,201 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalMultipleImport extends OSGiTestCase {

+	

+	ComponentInstance import2;

+	Factory fooProvider;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.4");

+		try {

+			import2 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		import2.dispose();

+		import2 = null;

+	}

+	

+	public void testSimple() {

+		// No provider -> valid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		

+		ComponentInstance foo = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2 ("+refs.length+")", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		FooService fs2 = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs2.foo());

+		sc.ungetService(refs[0]);

+		sc.ungetService(refs[1]);

+		

+		// Stop the second provider

+		foo2.dispose();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the foo provider

+		foo.stop();

+		

+		// No provider -> valid

+		assertTrue("Test component validity - 2", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo non-availability inside the composite - 1", refs.length, 0);

+		

+		foo.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component validity - 3", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo non-availability inside the composite - 2", refs.length, 0);

+	}

+	

+	public void testSimple2() {

+		// No provider -> Invalid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		

+		ComponentInstance foo1 = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo1 = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import2);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2 ("+refs.length+")", refs.length, 2);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		FooService fs2 = (FooService) sc.getService(refs[1]);

+		assertTrue("Test foo invocation", fs2.foo());

+		sc.ungetService(refs[0]);

+		sc.ungetService(refs[1]);

+		

+		// Stop the first provider

+		foo1.stop();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the second foo provider

+		foo2.dispose();

+		

+		// No provider -> Invalid

+		assertTrue("Test component validity - 2", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo non-availability inside the composite - 1", refs.length, 0);

+		

+		foo1.start();

+		assertTrue("Test component validity", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import2.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import2);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertEquals("Test foo non-availability inside the composite - 2", refs.length, 0);

+	}

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/SimpleImport.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/SimpleImport.java
new file mode 100644
index 0000000..9bcdc87
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/importer/SimpleImport.java
@@ -0,0 +1,184 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.importer;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleImport extends OSGiTestCase {

+	

+	ComponentInstance import1;

+	Factory fooProvider;

+

+	public void setUp() {

+		fooProvider = Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check fooProvider availability", fooProvider);

+		

+		Properties p = new Properties();

+		p.put("name", "importer");

+		Factory compFact = Utils.getFactoryByName(context, "composite.requires.1");

+		try {

+			import1 = compFact.createComponentInstance(p);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Cannot instantiate the component : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		import1.dispose();

+		import1 = null;

+	}

+	

+	public void testSimple() {

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 0 ("+import1.getState()+")", import1.getState() == ComponentInstance.INVALID);

+		

+		ComponentInstance foo = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity - 1", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the second provider

+		foo2.dispose();

+		assertTrue("Test component validity - 2", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the foo provider

+		foo.stop();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo.start();

+		assertTrue("Test component validity - 3", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import1.getState() == ComponentInstance.INVALID);

+	}

+	

+	public void testSimple2() {

+		// No provider -> Invalid

+		assertTrue("Test component invalidity", import1.getState() == ComponentInstance.INVALID);

+		

+		ComponentInstance foo1 = null;

+		Properties p = new Properties();

+		p.put("name", "foo");

+		try {

+			foo1 = fooProvider.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo component " + e.getMessage());

+		}

+		

+		ComponentInstance foo2 = null;

+		Properties p2 = new Properties();

+		p2.put("name", "foo2");

+		try {

+			foo2 = fooProvider.createComponentInstance(p2);

+		} catch(Exception e) {

+			fail("Fail to instantiate the foo2 component " + e.getMessage());

+		}

+		

+		// The foo service is available => import1 must be valid

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(import1);

+		ServiceReference[] refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 1", refs);

+		assertEquals("Test foo availability inside the composite - 1.2", refs.length, 1);

+		FooService fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// Stop the first provider

+		foo1.stop();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 2", refs);

+		assertEquals("Test foo availability inside the composite - 2.1 ("+refs.length+")", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		// stop the second foo provider

+		foo2.dispose();

+		

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 2", import1.getState() == ComponentInstance.INVALID);

+		

+		foo1.start();

+		assertTrue("Test component validity", import1.getState() == ComponentInstance.VALID);

+		sc = Utils.getServiceContext(import1);

+		refs = Utils.getServiceReferences(sc, FooService.class.getName(), null);

+		assertNotNull("Test foo availability inside the composite - 3", refs);

+		assertEquals("Test foo availability inside the composite - 3.1", refs.length, 1);

+		fs = (FooService) sc.getService(refs[0]);

+		assertTrue("Test foo invocation", fs.foo());

+		sc.ungetService(refs[0]);

+		

+		foo1.dispose(); 

+		// No provider -> Invalid

+		assertTrue("Test component invalidity - 3", import1.getState() == ComponentInstance.INVALID);

+	}	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/EmptyCompositeTest.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/EmptyCompositeTest.java
new file mode 100644
index 0000000..a729b33
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/EmptyCompositeTest.java
@@ -0,0 +1,222 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.infrastructure;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.composite.CompositeManager;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+

+public class EmptyCompositeTest extends OSGiTestCase {

+	

+	public void testEmptyCompositeCreation() {

+		Factory factory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = factory.createComponentInstance(props);

+		} catch (Exception e) {

+		    e.printStackTrace();

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		ComponentTypeDescription cd = ci.getFactory().getComponentDescription();

+		assertEquals("Check component type name", cd.getName(), "composite.empty");

+//		assertEquals("Check class name (" + cd.getClassName() + ")", cd.getClassName(), "composite");

+		assertEquals("Check offered service", cd.getprovidedServiceSpecification().length, 0);

+		assertEquals("Check configurable properties", cd.getProperties().length, 0);

+		

+		InstanceDescription id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state (" + id.getState() + ")", id.getState(), ComponentInstance.VALID);

+		

+		assertEquals("Check contained instance", id.getContainedInstances().length, 0);

+		

+		assertTrue("Check composite manager", ci instanceof CompositeManager);

+		CompositeManager cm = (CompositeManager) ci;

+		ServiceContext sc = cm.getServiceContext();

+		try {

+			assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(), null).length, context.getServiceReferences(Factory.class.getName(), null).length);

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e.getMessage());

+		}

+		ci.dispose();

+	}

+	

+	public void testInstanceCreation1() {

+		Factory factory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = factory.createComponentInstance(props);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		assertTrue("Check composite manager", ci instanceof CompositeManager);

+		CompositeManager cm = (CompositeManager) ci;

+		ServiceContext sc = cm.getServiceContext();

+		try {

+			assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(), null).length, context.getServiceReferences(Factory.class.getName(), null).length);

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e.getMessage());

+		}

+		

+		Properties props2 = new Properties();

+		props2.put("name", "empty2");

+		ComponentInstance ci2 = null;

+		try {

+			ci2 = factory.createComponentInstance(props2, sc);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		InstanceDescription id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 1);

+		InstanceDescription id2 = id.getContainedInstances()[0];

+		assertEquals("Check composite instance name", id2.getName(), "empty2");

+		assertEquals("Check composite instance state", id2.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id2.getContainedInstances().length, 0);

+		

+		ci2.dispose();

+		id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 0);

+		

+		ci.dispose();

+	}

+	

+	public void testInstanceCreation2() {

+		Factory factory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		assertTrue("Check composite manager", ci instanceof CompositeManager);

+		CompositeManager cm = (CompositeManager) ci;

+		ServiceContext sc = cm.getServiceContext();

+		try {

+			assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(), null).length, context.getServiceReferences(Factory.class.getName(), null).length);

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e.getMessage());

+		}

+		

+		Factory factory2 = Utils.getFactoryByName(sc, "composite.empty");

+		assertNotNull("Check factory2 not null", factory2);

+		Properties props2 = new Properties();

+		props2.put("name", "empty2");

+		ComponentInstance ci2 = null;

+		try {

+			ci2 = factory2.createComponentInstance(props2);

+		} catch(Exception e) {

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		InstanceDescription id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 1);

+		InstanceDescription id2 = id.getContainedInstances()[0];

+		assertEquals("Check composite instance name", id2.getName(), "empty2");

+		assertEquals("Check composite instance state", id2.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id2.getContainedInstances().length, 0);

+		

+		ci2.dispose();

+		id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 0);

+		

+		ci.dispose();

+	}

+	

+	public void testInstanceCreation3() {

+		Factory factory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		assertTrue("Check composite manager", ci instanceof CompositeManager);

+		CompositeManager cm = (CompositeManager) ci;

+		ServiceContext sc = cm.getServiceContext();

+		try {

+			assertEquals("Check number of factories imported", sc.getServiceReferences(Factory.class.getName(), null).length, context.getServiceReferences(Factory.class.getName(), null).length);

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e.getMessage());

+		}

+		

+		Factory factory2 = Utils.getFactoryByName(sc, "composite.empty");

+		assertNotNull("Check factory2 not null", factory2);

+		Properties props2 = new Properties();

+		props2.put("name", "empty2");

+		ComponentInstance ci2 = null;

+		try {

+			ci2 = factory2.createComponentInstance(props2, sc);

+		} catch(Exception e) {

+			fail("Unacceptable configuration : " + e.getMessage());

+		}

+		

+		InstanceDescription id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 1);

+		InstanceDescription id2 = id.getContainedInstances()[0];

+		assertEquals("Check composite instance name", id2.getName(), "empty2");

+		assertEquals("Check composite instance state", id2.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id2.getContainedInstances().length, 0);

+		

+		ci2.dispose();

+		id = ci.getInstanceDescription();

+		assertEquals("Check composite instance name", id.getName(), "empty");

+		assertEquals("Check composite instance state", id.getState(), ComponentInstance.VALID);

+		assertEquals("Check contained instance", id.getContainedInstances().length, 0);

+		

+		ci.dispose();

+	}

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/FactoryManagementTest.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/FactoryManagementTest.java
new file mode 100644
index 0000000..8e238a3
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/FactoryManagementTest.java
@@ -0,0 +1,263 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.infrastructure;

+

+import java.util.Dictionary;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.FactoryStateListener;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.UnacceptableConfiguration;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+public class FactoryManagementTest extends OSGiTestCase {

+	

+	private FakeFactory fake1 = new FakeFactory("fake");

+	private FakeFactory fake2 = new FakeFactory("fake2");

+	

+	private Factory emptyFactory;

+	private ComponentInstance empty;

+	

+	private class FakeFactory implements Factory {

+		

+		private String m_name;

+		public FakeFactory(String name) { m_name = name; } 

+

+		public ComponentInstance createComponentInstance(Dictionary arg0) throws UnacceptableConfiguration { return null; }

+		public ComponentInstance createComponentInstance(Dictionary arg0, ServiceContext arg1) throws UnacceptableConfiguration { return null; }

+		public Element getDescription() { return null; }

+		public String getName() { return m_name; }

+		public boolean isAcceptable(Dictionary arg0) { return false; }

+		public void reconfigure(Dictionary arg0) throws UnacceptableConfiguration {	}

+        public void addFactoryStateListener(FactoryStateListener arg0) { }

+        public List getMissingHandlers() { return null;  }

+        public List getRequiredHandlers() { return null;  }

+        public void removeFactoryStateListener(FactoryStateListener arg0) { }

+        public ComponentTypeDescription getComponentDescription() { return null; }

+        public String getClassName() { return ""; }

+        public int getState() { return Factory.VALID; }

+        public BundleContext getBundleContext() { return context; }

+

+	}

+	

+	public void setUp() {

+		emptyFactory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty-1");

+		try {

+			empty = emptyFactory.createComponentInstance(props);

+		} catch (Exception e) { fail("Cannot create empty instance " + e.getMessage()); }

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testOneLevelExposition() {

+		ServiceReference[] parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		ServiceContext sc = Utils.getServiceContext(empty);

+		ServiceReference[] internalFactoryReferences = Utils.getServiceReferences(sc, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories", parentsFactoryReferences.length, internalFactoryReferences.length);

+		

+		for(int i = 0; i < parentsFactoryReferences.length; i++) {

+			Factory factory = (Factory) context.getService(parentsFactoryReferences[i]);

+			assertTrue("Check the avaibility of " + factory.getName(), isExposed(factory, internalFactoryReferences, sc));

+		}

+	}

+	

+	public void testTwoLevelExposition() {

+		ServiceReference[] parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		ServiceContext sc1 = Utils.getServiceContext(empty);

+		ServiceReference[] Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch (Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		ServiceReference[] Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		for(int i = 0; i < Level1FactoryReferences.length; i++) {

+			Factory factory = (Factory) context.getService(parentsFactoryReferences[i]);

+			assertTrue("Check the avaibility of " + factory.getName(), isExposed(factory, Level2FactoryReferences, sc2));

+		}

+		

+		empty2.dispose();

+	}

+	

+	public void testDynamism() {

+		ServiceReference[] parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		ServiceContext sc1 = Utils.getServiceContext(empty);

+		ServiceReference[] Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch (Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		ServiceReference[] Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		for(int i = 0; i < Level1FactoryReferences.length; i++) {

+			Factory factory = (Factory) context.getService(parentsFactoryReferences[i]);

+			assertTrue("Check the avaibility of " + factory.getName(), isExposed(factory, Level2FactoryReferences, sc2));

+		}

+		

+		// Publish fake1

+		ServiceRegistration reg1 = context.registerService(Factory.class.getName(), fake1, null);

+		

+		parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		sc1 = Utils.getServiceContext(empty);

+		Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		sc2 = Utils.getServiceContext(empty2);

+		Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1.1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		// 	Publish fake2

+		ServiceRegistration reg2 = context.registerService(Factory.class.getName(), fake2, null);

+		

+		parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		sc1 = Utils.getServiceContext(empty);

+		Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		sc2 = Utils.getServiceContext(empty2);

+		Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1.1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		reg1.unregister();

+		

+		parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		sc1 = Utils.getServiceContext(empty);

+		Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		sc2 = Utils.getServiceContext(empty2);

+		Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1.1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		reg2.unregister();

+		

+		parentsFactoryReferences = Utils.getServiceReferences(context, Factory.class.getName(), null);

+		sc1 = Utils.getServiceContext(empty);

+		Level1FactoryReferences = Utils.getServiceReferences(sc1, Factory.class.getName(), null);

+		sc2 = Utils.getServiceContext(empty2);

+		Level2FactoryReferences = Utils.getServiceReferences(sc2, Factory.class.getName(), null);

+		

+		assertEquals("Check the number of available factories - 1.1", parentsFactoryReferences.length, Level1FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.2", parentsFactoryReferences.length, Level2FactoryReferences.length);

+		assertEquals("Check the number of available factories - 1.3", Level1FactoryReferences.length, Level2FactoryReferences.length);

+		

+		empty2.dispose();

+	}

+	

+	public void testInvocation() {

+		ServiceContext sc1 = Utils.getServiceContext(empty);		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch (Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		

+		Factory fact1 = Utils.getFactoryByName(sc2, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props);

+		} catch (Exception e) { e.printStackTrace(); fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc2, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2);

+		} catch (Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());		

+		assertNotNull("Check ref existency", ref);

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		client.dispose();

+		provider.dispose();

+		empty2.dispose();

+	}

+	

+	

+	

+	

+	private boolean isExposed(Factory fact, ServiceReference[] refs, ServiceContext sc) {

+		for(int i = 0; i < refs.length; i++) {

+			Factory f = (Factory) sc.getService(refs[i]);

+			if(fact.getName().equals(f.getName())) {

+				sc.ungetService(refs[i]);

+				return true; 

+			}

+			sc.ungetService(refs[i]);

+		}

+		return false;

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/InfrastructureTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/InfrastructureTestSuite.java
new file mode 100644
index 0000000..051ba7b
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/InfrastructureTestSuite.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.infrastructure;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class InfrastructureTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Service Context Infrastructure Test", bc);

+		ots.addTestSuite(ServiceRegistryTest.class);

+		ots.addTestSuite(EmptyCompositeTest.class);

+		ots.addTestSuite(FactoryManagementTest.class);

+		ots.addTestSuite(ServiceRangeTest.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRangeTest.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRangeTest.java
new file mode 100644
index 0000000..740f129
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRangeTest.java
@@ -0,0 +1,482 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.infrastructure;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class ServiceRangeTest extends OSGiTestCase {

+	

+	private Factory emptyFactory;

+	private ComponentInstance empty;

+

+	

+	public void setUp() {

+		emptyFactory = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty-1");

+		try {

+			empty = emptyFactory.createComponentInstance(props);

+		} catch(Exception e) { fail("Cannot create empty instance " + e.getMessage()); }

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testLevelOne1() {

+		ServiceContext sc2 = Utils.getServiceContext(empty);

+		

+		Factory fact1 = Utils.getFactoryByName(sc2, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc2, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		// Check visibility 

+		assertNotNull("Check foo service visible inside the composite", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the context", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		provider.dispose();

+		client.dispose();

+		 

+		assertNull("Check foo service invisible inside the composite", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible from the context", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+	}

+	

+	public void testLevelOne2() {

+		ServiceContext sc2 = Utils.getServiceContext(empty);

+		

+		Factory fact1 = Utils.getFactoryByName(sc2, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props, sc2);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc2, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2, sc2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		// Check visibility 

+		assertNotNull("Check foo service visible inside the composite", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the context", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+	}

+	

+	public void testLevelOne3() {

+		ServiceContext sc2 = Utils.getServiceContext(empty);

+		

+		Factory fact1 = Utils.getFactoryByName(context, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props, sc2);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(context, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2, sc2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		// Check visibility 

+		assertNotNull("Check foo service visible inside the composite", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the context", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+	}

+	

+	public void testLevelTwo1() {

+		ServiceContext sc1 = Utils.getServiceContext(empty);		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		

+		Factory fact1 = Utils.getFactoryByName(sc2, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc2, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		//	Check visibility 

+		assertNotNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		empty2.dispose();

+	}

+	

+	public void testLevelTwo2() {

+		ServiceContext sc1 = Utils.getServiceContext(empty);		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		

+		Factory fact1 = Utils.getFactoryByName(sc1, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props, sc2);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc1, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2, sc2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		//	Check visibility 

+		assertNotNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		empty2.dispose();

+	}

+	

+	public void testLevelTwo3() {

+		ServiceContext sc1 = Utils.getServiceContext(empty);		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		

+		Factory fact1 = Utils.getFactoryByName(context, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props, sc2);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(context, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2, sc2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		//	Check visibility 

+		assertNotNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		empty2.dispose();

+	}

+	

+	public void testLevelTwo4() {

+		ServiceContext sc1 = Utils.getServiceContext(empty);		

+		Factory fact = Utils.getFactoryByName(sc1, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty2");

+		ComponentInstance empty2 = null;

+		try {

+			empty2 = fact.createComponentInstance(p);

+		} catch(Exception e) {

+			fail("Cannot instantiate empty2 instance : " + e.getMessage());

+		}

+		

+		ServiceContext sc2 = Utils.getServiceContext(empty2);

+		

+		Factory fact1 = Utils.getFactoryByName(sc2, "SimpleCheckServiceProvider");

+		Properties props = new Properties();

+		props.put("name", "client");

+		ComponentInstance client = null;

+		try {

+			client = fact1.createComponentInstance(props, sc2);

+		} catch(Exception e) { fail("Cannot instantiate the client : " + e.getMessage()); }

+		

+		Factory fact2 = Utils.getFactoryByName(sc2, "FooProviderType-1");

+		Properties props2 = new Properties();

+		props2.put("name", "provider");

+		ComponentInstance provider = null;

+		try {

+			provider = fact2.createComponentInstance(props2, sc2);

+		} catch(Exception e) {

+			fail("Cannot instantiate the provider : " + e.getMessage());

+		}

+		

+		ServiceReference ref = sc2.getServiceReference(CheckService.class.getName());

+		CheckService check = (CheckService) sc2.getService(ref);

+		

+		assertTrue("Check invocation", check.check());

+		

+		sc2.ungetService(ref);

+		

+		//	Check visibility 

+		assertNotNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNotNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		// Check invisibilty

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		

+		client.dispose();

+		provider.dispose();

+		 

+		assertNull("Check foo service visible inside the composite 2", sc2.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service visible inside the composite 2", sc2.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the composite 1", sc1.getServiceReference(FooService.class.getName()));

+		assertNull("Check check service invisible inside the composite 1", sc1.getServiceReference(CheckService.class.getName()));

+		assertNull("Check foo service invisible inside the global", context.getServiceReference(FooService.class.getName()));

+		try {

+			assertNull("Check check service invisible inside the context", context.getServiceReferences(CheckService.class.getName(), "(instance.name=client)"));

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e);

+		}

+		empty2.dispose();

+	}

+	

+	

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRegistryTest.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRegistryTest.java
new file mode 100644
index 0000000..0b76bcb
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/infrastructure/ServiceRegistryTest.java
@@ -0,0 +1,245 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.infrastructure;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.InstanceStateListener;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.context.ServiceRegistry;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceEvent;

+import org.osgi.framework.ServiceListener;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.ServiceRegistration;

+

+public class ServiceRegistryTest extends OSGiTestCase {

+	

+	private class svcListener implements ServiceListener {

+		public int registration = 0;

+		public int unregistration = 0;

+		public int modification = 0;

+		public void serviceChanged(ServiceEvent ev) {

+			if(ev.getType() == ServiceEvent.REGISTERED) { registration++; }

+			if(ev.getType() == ServiceEvent.UNREGISTERING) { unregistration++; }

+			if(ev.getType() == ServiceEvent.MODIFIED) { modification++; }

+		}

+	}

+	

+	private class barProvider implements BarService {

+

+		public boolean bar() { return true; }

+

+		public Properties getProps() { return null; }

+

+	}

+	

+	private class FakeComponent implements ComponentInstance {

+

+		public ComponentTypeDescription getComponentDescription() {

+			return null;

+		}

+

+		public BundleContext getContext() {

+			return null;

+		}

+

+		public ComponentFactory getFactory() {

+			return null;

+		}

+

+		public InstanceDescription getInstanceDescription() {

+			return null;

+		}

+

+		public String getInstanceName() {

+			return null;

+		}

+

+		public int getState() {

+			return 0;

+		}

+

+		public boolean isStarted() {

+			return false;

+		}

+

+		public void reconfigure(Dictionary dictionary) { }

+

+		public void start() { }

+

+		public void stop() { }

+		

+		public void dispose() { }

+

+		public void addInstanceStateListener(InstanceStateListener arg0) { }

+

+		public void removeInstanceStateListener(InstanceStateListener arg0) { }

+		

+	}

+	

+	public void testRegistrationAndListener() {

+		ComponentInstance im = new FakeComponent();

+		ComponentInstance im2 = new FakeComponent();

+		ServiceRegistry registry = new ServiceRegistry(context);

+		assertNotNull("Assert registry not null", registry);

+		svcListener all = new svcListener();

+		try {

+			assertNull("Check that there is no available service", registry.getServiceReferences(null, null));

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+		registry.addServiceListener(all);

+		

+		ServiceRegistration reg1 = registry.registerService(im, BarService.class.getName(), new barProvider(), null);

+		

+		try {

+			assertEquals("Check number of registred service", 1, registry.getServiceReferences(null, null).length);

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); 

+		 }

+	

+	    ServiceRegistration reg2 = registry.registerService(im2, BarService.class.getName(), new barProvider(), null);

+			

+	   try {

+			assertEquals("Check number of registred service", 2, registry.getServiceReferences(null, null).length);

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+	    

+		assertEquals("Check the number of registration", 2, all.registration);

+		

+		Properties props = new Properties();

+		props.put("foo", "bar");

+		reg1.setProperties(props);

+		assertEquals("Check the number of modification", 1, all.modification);

+		

+		reg1.unregister();

+		assertEquals("Check the number of unregistration", 1, all.unregistration);

+		

+		reg2.setProperties(props);

+		assertEquals("Check the number of modification", 2, all.modification);

+		

+		reg2.unregister();

+		assertEquals("Check the number of unregistration", 2, all.unregistration);

+		

+		registry.removeServiceListener(all);

+	}

+	

+	public void testRegistrationAndFilter() {

+		ComponentInstance im = new FakeComponent();

+		ComponentInstance im2 = new FakeComponent();

+		ServiceRegistry registry = new ServiceRegistry(context);

+		svcListener filtered = new svcListener();

+		

+		try {

+			assertNull("Check that there is no available service", registry.getServiceReferences(null, null));

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+		  

+		registry.addServiceListener(filtered, "(foo=bar)");

+		

+		Properties props = new Properties();

+		props.put("foo", "bar");

+		ServiceRegistration reg1 = registry.registerService(im, BarService.class.getName(), new barProvider(), props);

+		

+		try {

+			assertEquals("Check number of registred service", 1, registry.getServiceReferences(null, null).length);

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+		  

+	  ServiceRegistration reg2 = registry.registerService(im2, BarService.class.getName(), new barProvider(), null);

+			

+	   try {

+			assertEquals("Check number of registred service", 2, registry.getServiceReferences(null, null).length);

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+			  

+		assertEquals("Check the number of registration", 1, filtered.registration);

+		

+		reg2.setProperties(props);

+		assertEquals("Check the number of modification", 1, filtered.modification);

+		// Follow the OSGi semantics of filters

+		

+		reg1.unregister();

+		reg2.unregister();

+		assertEquals("Check the number of unregistration", 2, filtered.unregistration);

+		registry.removeServiceListener(filtered);

+	}

+	

+	public void testGetService() {

+		ComponentInstance im = new FakeComponent();

+		ComponentInstance im2 = new FakeComponent();

+		ServiceRegistry registry = new ServiceRegistry(context);

+		

+		try {

+			assertNull("Check that there is no available service", registry.getServiceReferences(null, null));

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+		

+		Properties props = new Properties();

+		props.put("foo", "bar");

+		ServiceRegistration reg1 = registry.registerService(im, BarService.class.getName(), new barProvider(), props);

+		

+		ServiceReference ref = registry.getServiceReference(BarService.class.getName());

+		assertNotNull("Check ref not null", ref);

+		assertEquals("Test property", ref.getProperty("foo"), "bar");

+		BarService bar = (BarService) registry.getService(im2, ref);

+		assertTrue("Test invocation", bar.bar());

+		

+		reg1.unregister();

+		ref = registry.getServiceReference(BarService.class.getName());

+		assertNull("Check ref null", ref);

+	}

+	

+	public void testGetFilteredService() {

+		ComponentInstance im = new FakeComponent();

+		ComponentInstance im2 = new FakeComponent();

+		ServiceRegistry registry = new ServiceRegistry(context);

+		

+		try {

+			assertNull("Check that there is no available service", registry.getServiceReferences(null, null));

+		} catch (InvalidSyntaxException e) { fail("Cannot query the registry : " + e.getMessage()); }

+		

+		Properties props = new Properties();

+		props.put("foo", "bar");

+		ServiceRegistration reg1 = registry.registerService(im, BarService.class.getName(), new barProvider(), props);

+		ServiceRegistration reg2 = registry.registerService(im2, BarService.class.getName(), new barProvider(), null);

+		

+		ServiceReference[] ref = null;

+		try {

+			ref = registry.getServiceReferences(BarService.class.getName(), "(foo=bar)");

+		} catch (InvalidSyntaxException e) { fail("Registry query fail : " + e.getMessage()); }

+		assertNotNull("Check ref not null", ref);

+		assertEquals("Check ref count", ref.length, 1);

+		assertEquals("Test property", ref[0].getProperty("foo"), "bar");

+		BarService bar = (BarService) registry.getService(im2, ref[0]);

+		assertTrue("Test invocation", bar.bar());

+		

+		ref = null;

+		reg1.unregister();

+		try {

+			ref = registry.getServiceReferences(BarService.class.getName(), "(bar=foo)");

+		} catch (InvalidSyntaxException e) { fail("Registry query fail : " + e.getMessage()); }

+		assertNull("Check ref null", ref);

+		

+		reg2.unregister();

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instance/SimpleInstance.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instance/SimpleInstance.java
new file mode 100644
index 0000000..433f62f
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instance/SimpleInstance.java
@@ -0,0 +1,267 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instance;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleInstance extends OSGiTestCase {

+

+	private ComponentFactory fooFactory1, fooFactory2;

+    private ComponentFactory compoFactory;

+	private ComponentInstance empty;

+	

+	

+	public void setUp() {

+        fooFactory1 = (ComponentFactory) Utils.getFactoryByName(context, "FooProviderType-1");

+        fooFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+        compoFactory = (ComponentFactory) Utils.getFactoryByName(context, "composite.inst.1");

+		Factory fact = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty-X");

+		try {

+			empty = fact.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot create the empty composite : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testCreation() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Cannot instantiate under from " + compoFactory.getName() + " -> " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailability() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+       

+		assertNotNull("Check service availability", sc.getServiceReference(FooService.class.getName()));

+        assertEquals("Check service provider", Utils.getServiceReferences(sc, FooService.class.getName(), null).length, 2);

+		

+		under.dispose();

+	}

+	

+	public void testCreationLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailabilityLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under-X");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+        

+        assertNotNull("Check service availability", sc2.getServiceReference(FooService.class.getName()));

+        assertEquals("Check service providers", Utils.getServiceReferences(sc2, FooService.class.getName(), null).length, 2);

+		

+		under.dispose();

+	}

+	

+	public void testFactoryManagement() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		fooFactory1.stop();

+		assertTrue("Check instance invalidity - 2", under.getState() == ComponentInstance.INVALID);

+        

+        fooFactory1.start();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+        

+		fooFactory2.stop();

+        assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		

+		fooFactory2.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fooFactory1.start();

+		fooFactory2.start();

+	}

+	

+	public void testFactoryManagementLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+        

+        fooFactory1.stop();

+        assertTrue("Check instance invalidity - 2", under.getState() == ComponentInstance.INVALID);

+        

+        fooFactory1.start();

+        assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+        

+        fooFactory2.stop();

+        assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+        

+        fooFactory2.start();

+        assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+        

+        under.dispose();

+        fooFactory1.start();

+        fooFactory2.start();

+	}

+	

+	public void atestArchitecture() { //TODO : to reactive

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = compoFactory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		ServiceReference ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		Architecture arch = (Architecture) context.getService(ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		InstanceDescription[] contained = id.getContainedInstances();

+		assertEquals("Check contained instances count (" + contained.length + ")", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.INVALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 0);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/ConfigurableInstantiation.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/ConfigurableInstantiation.java
new file mode 100644
index 0000000..a7de283
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/ConfigurableInstantiation.java
@@ -0,0 +1,101 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class ConfigurableInstantiation extends OSGiTestCase {

+

+	private ComponentFactory acceptF;

+	private ComponentFactory refuse1F;

+	private ComponentFactory refuse2F;

+	

+	public void setUp() {

+		acceptF = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.5-accept");

+		refuse1F = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.5-refuse1");

+		refuse2F = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.5-refuse2");

+		

+	}

+	

+	public void tearDown() { }

+	

+	public void testAccept() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = acceptF.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		ServiceReference ref = sc.getServiceReference(FooService.class.getName());

+		assertNotNull("Check refs not null", ref);

+		FooService foo = (FooService) sc.getService(ref);

+		Properties p = foo.fooProps();

+		boolean b = ((Boolean) p.get("boolProp")).booleanValue();

+		String s = (String) p.get("strProp");

+		int i = ( (Integer) p.get("intProp")).intValue();

+		assertTrue("Test boolean", b);

+		assertEquals("Test string", s, "foo");

+		

+		assertEquals("Test int", i, 5); // The code fix to 5.

+		under.dispose();

+	}

+	

+	public void testRefuse1() {

+		Properties props = new Properties();

+		props.put("name", "under-ref1");

+		ComponentInstance under = null;

+		try {

+			under = refuse1F.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		

+		assertTrue("Check that under is not valid", under.getState() == ComponentInstance.INVALID);

+        

+        under.dispose();

+	}

+	

+	public void testRefuse2() {

+		Properties props = new Properties();

+		props.put("name", "under-ref2");

+		ComponentInstance under = null;

+		try {

+			under = refuse2F.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		

+		assertTrue("Check that under is not valid", under.getState() == ComponentInstance.INVALID);

+        

+        under.dispose();

+	}

+	

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/InstantiatorTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/InstantiatorTestSuite.java
new file mode 100644
index 0000000..7497b3a
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/InstantiatorTestSuite.java
@@ -0,0 +1,38 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class InstantiatorTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Composite Service Instantiation Test Suite", bc);

+		ots.addTestSuite(SimpleInstantiation.class);

+		ots.addTestSuite(OptionalInstantiation.class);

+		ots.addTestSuite(MultipleInstantiation.class);

+		ots.addTestSuite(OptionalMultipleInstantiation.class);

+		ots.addTestSuite(ConfigurableInstantiation.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/MultipleInstantiation.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/MultipleInstantiation.java
new file mode 100644
index 0000000..066f29d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/MultipleInstantiation.java
@@ -0,0 +1,288 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleInstantiation extends OSGiTestCase {

+

+	private ComponentFactory bar2Factory;

+	private ComponentInstance empty;

+	

+	public void setUp() {

+		bar2Factory = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.2");

+		Factory fact = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		try {

+			empty = fact.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot create the empty composite : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testCreation() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailability() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc.getServiceReference(BarService.class.getName()));

+		int count = Utils.getServiceReferences(sc, BarService.class.getName(), null).length;

+		assertEquals("Check service provider number : " + count, count, 3);

+		

+		under.dispose();

+	}

+	

+	public void testCreationLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailabilityLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc2.getServiceReference(BarService.class.getName()));

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 3);

+		

+		under.dispose();

+	}

+	

+	public void testFactoryManagement() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 2);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 1);

+		

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 0);

+		

+		fact1.start();

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 1);

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testFactoryManagementLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 2);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 1);

+		

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 0);

+		

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 1);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	public void testArchitecture() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		ServiceReference ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		Architecture arch = (Architecture) context.getService(ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		InstanceDescription[] contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 3);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.2");

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 2);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.2");

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.2");

+

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.INVALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 0);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.2");

+

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.2");

+

+		context.ungetService(ref);

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalInstantiation.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalInstantiation.java
new file mode 100644
index 0000000..64f80f9
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalInstantiation.java
@@ -0,0 +1,279 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalInstantiation extends OSGiTestCase {

+

+	private ComponentFactory bar1Factory;

+	private ComponentInstance empty;

+	

+	public void setUp() {

+		bar1Factory = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.3");

+		Factory fact = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		try {

+			empty = fact.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot create the empty composite : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testCreation() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailability() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc.getServiceReference(BarService.class.getName()));

+		

+		under.dispose();

+	}

+	

+	public void testCreationLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailabilityLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc2.getServiceReference(BarService.class.getName()));

+		

+		under.dispose();

+	}

+	

+	public void testFactoryManagement() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		

+		fact3.stop();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertNull("Check that no Bar Service is available", sc.getServiceReference(BarService.class.getName()));

+		

+		fact1.start();

+		assertTrue("Check instance validity - 5", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testFactoryManagementLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		

+		fact3.stop();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		

+		fact1.start();

+		assertTrue("Check instance validity - 5", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testArchitecture() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		

+		ServiceReference ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		Architecture arch = (Architecture) context.getService(ref);

+		assertNotNull("Check architecture", arch);

+		InstanceDescription id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		InstanceDescription[] contained = id.getContainedInstances();

+		assertNotNull("Check contained not null", contained);

+		assertEquals("Check contained instances count ("+contained.length+") - 1", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.3");

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.3");

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.3");

+

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 0);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.3");

+

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.3");

+

+		context.ungetService(ref);

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalMultipleInstantiation.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalMultipleInstantiation.java
new file mode 100644
index 0000000..19984d0
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/OptionalMultipleInstantiation.java
@@ -0,0 +1,203 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+

+public class OptionalMultipleInstantiation extends OSGiTestCase {

+

+	private ComponentFactory bar2Factory;

+	private ComponentInstance empty;

+	

+	public void setUp() {

+		bar2Factory = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.4");

+		assertNotNull("Check bar2factory availability", bar2Factory);

+		

+		Factory fact = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty");

+		try {

+			empty = fact.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot create the empty composite : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testCreation() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailability() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc.getServiceReference(BarService.class.getName()));

+		int count = Utils.getServiceReferences(sc, BarService.class.getName(), null).length;

+		assertEquals("Check service provider number : " + count, count, 3);

+		

+		under.dispose();

+	}

+	

+	public void testCreationLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailabilityLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc2.getServiceReference(BarService.class.getName()));

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 3);

+		

+		under.dispose();

+	}

+	

+	public void testFactoryManagement() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 2);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 1);

+		

+		fact3.stop();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 0);

+		

+		fact1.start();

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc, BarService.class.getName(), null).length, 1);

+		assertTrue("Check instance validity - 5", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testFactoryManagementLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar2Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 2);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 1);

+		

+		fact3.stop();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 0);

+		

+		fact1.start();

+		assertTrue("Check instance validity - 5", under.getState() == ComponentInstance.VALID);

+		assertEquals("Check service provider number", Utils.getServiceReferences(sc2, BarService.class.getName(), null).length, 1);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	

+	

+	

+	

+	

+	

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/SimpleInstantiation.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/SimpleInstantiation.java
new file mode 100644
index 0000000..14b1e1d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/instantiator/SimpleInstantiation.java
@@ -0,0 +1,265 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.instantiator;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleInstantiation extends OSGiTestCase {

+

+	private ComponentFactory bar1Factory;

+	private ComponentInstance empty;

+	

+	public void setUp() {

+		bar1Factory = (ComponentFactory) Utils.getFactoryByName(context, "composite.bar.1");

+		Factory fact = Utils.getFactoryByName(context, "composite.empty");

+		Properties props = new Properties();

+		props.put("name", "empty-X");

+		try {

+			empty = fact.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot create the empty composite : " + e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		empty.dispose();

+		empty = null;

+	}

+	

+	public void testCreation() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailability() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc.getServiceReference(BarService.class.getName()));

+		

+		under.dispose();

+	}

+	

+	public void testCreationLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		under.dispose();

+	}

+	

+	public void testServiceAvailabilityLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under-X");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}	

+		assertTrue("Check instance validity", under.getState() == ComponentInstance.VALID);

+		ServiceContext sc2 = Utils.getServiceContext(under);

+		assertNotNull("Check service availability", sc2.getServiceReference(BarService.class.getName()));

+		

+		under.dispose();

+	}

+	

+	public void testFactoryManagement() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testFactoryManagementLevel2() {

+		ServiceContext sc = Utils.getServiceContext(empty);

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props, sc);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		assertTrue("Check instance validity - 1", under.getState() == ComponentInstance.VALID);

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+	

+	public void testArchitecture() {

+		Properties props = new Properties();

+		props.put("name", "under");

+		ComponentInstance under = null;

+		try {

+			under = bar1Factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate under : " + e.getMessage());

+		}

+		ServiceReference ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		Architecture arch = (Architecture) context.getService(ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		InstanceDescription[] contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+		

+		ComponentFactory fact1 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-1");

+		ComponentFactory fact2 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-2");

+		ComponentFactory fact3 = (ComponentFactory) Utils.getFactoryByName(context, "FooBarProviderType-3");

+		

+		fact1.stop();

+		assertTrue("Check instance validity - 2", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+		

+		fact2.stop();

+		assertTrue("Check instance validity - 3", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		fact3.stop();

+		assertTrue("Check instance invalidity", under.getState() == ComponentInstance.INVALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.INVALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 0);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		fact1.start();

+		assertTrue("Check instance validity - 4", under.getState() == ComponentInstance.VALID);

+		ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "under");

+		assertNotNull("Check architecture availability", ref);

+		arch = (Architecture) context.getService(ref);

+		id = arch.getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		contained = id.getContainedInstances();

+		assertEquals("Check contained instances count", contained.length, 1);

+		assertEquals("Check that no object are created" , id.getCreatedObjects().length, 0);

+		assertEquals("Check instance name" , id.getName(), "under");

+		assertEquals("Check component type name" , id.getComponentDescription().getName(), "composite.bar.1");

+

+		under.dispose();

+		fact2.start();

+		fact3.start();

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/ProvidesTestSuite.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/ProvidesTestSuite.java
new file mode 100644
index 0000000..413ff58
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/ProvidesTestSuite.java
@@ -0,0 +1,43 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ProvidesTestSuite {

+

+    public static Test suite(BundleContext bc) {

+        OSGiTestSuite ots = new OSGiTestSuite("Composite Service Providing Test Suite", bc);

+        ots.addTestSuite(TestComp0.class);

+        ots.addTestSuite(TestComp1.class);

+        ots.addTestSuite(TestComp2.class);

+        ots.addTestSuite(TestComp3.class);

+        ots.addTestSuite(TestComp4.class);

+        ots.addTestSuite(TestComp5.class);

+        ots.addTestSuite(TestComp6.class);

+        ots.addTestSuite(TestComp7.class);

+        ots.addTestSuite(TestComp8.class);

+        

+        return ots;

+    }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp0.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp0.java
new file mode 100644
index 0000000..6d5458d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp0.java
@@ -0,0 +1,338 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.service.Toto;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp0 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    private ComponentFactory tataFactory2;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+           fail("Cannot create an instance : " + e.getMessage());

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            fail("Cannot create an instance : " + e.getMessage());

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-0");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            fail("Cannot create an instance : " + e.getMessage());

+        }

+    }

+    

+    public void tearDown() {

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertNotNull("Assert toto service - 1", context.getServiceReference(Toto.class.getName()));

+        assertTrue("Assert under state - 2", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 3", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        Integer tataStr = (Integer) props.get("tataStr");

+        Integer tataStrs = (Integer) props.get("tataStrs");

+        Integer tata_2 = (Integer) props.get("tata_2");

+        Integer tata_3 = (Integer) props.get("tata_3");

+        Integer tata1 = (Integer) props.get("tata1");

+        Integer tata1_1 = (Integer) props.get("tata1_1");

+        Integer tata5 = (Integer) props.get("tata5");

+        Integer tata5_1 = (Integer) props.get("tata5_1");

+        Integer tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 3", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 3", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 3", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 3", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 3", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 3", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 3", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 3", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 3", tata5_2.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 4", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        assertEquals("Assert tataStr - 4", tataStr.intValue(), 2);

+        assertEquals("Assert tataStrs - 4", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 4", tata_2.intValue(), 2);

+        assertEquals("Assert tata_3 - 4", tata_3.intValue(), 2);

+        assertEquals("Assert tata1 - 4", tata1.intValue(), 2);

+        assertEquals("Assert tata1_1 - 4", tata1_1.intValue(), 2);

+        assertEquals("Assert tata5 - 4", tata5.intValue(), 2);

+        assertEquals("Assert tata5_1 - 4", tata5_1.intValue(), 2);

+        assertEquals("Assert tata5_2 - 4", tata5_2.intValue(), 2);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 6", toto.intValue(), 3);

+        assertEquals("Assert toto_2 - 6", toto_2.intValue(), 3);

+        assertEquals("Assert toto_3 - 6", toto_3.intValue(), 3);

+        assertEquals("Assert toto_4 - 6", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 6", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 6", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 6", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 6", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 6", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 6", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 6", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 6", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 6", tata5_2.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        totoProv.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    private void invokeArrays(Tota tota) {

+        

+        int[] a = new int[] {1,2,3};

+        assertEquals("Assert invoke tataint[]", tota.tataInts(a), a);

+        

+        long[] b = new long[] {1,2,3};

+        assertEquals("Assert invoke tataLong[]", tota.tataLongs(b), b);

+        

+        double[] c = new double[] {1,2,3};

+        assertEquals("Assert invoke tataDouble[]", tota.tataDoubles(c), c);

+        

+        char[] d = new char[] {'a','b', 'c'};

+        assertEquals("Assert invoke tataChar[]", tota.tataChars(d), d);

+        

+        boolean[] e = new boolean[] {true, false};

+        assertEquals("Assert invoke tataBoolean[]", tota.tataBooleans(e), e);

+        

+        byte[] f = new byte[] {(byte) 1};

+        assertEquals("Assert invoke tataByte[]", tota.tataBytes(f), f);

+        

+        short[] g = new short[] {(short) 1};

+        assertEquals("Assert invoke tataShort[]", tota.tataShorts(g), g);

+        

+        float[] h = new float[] {5,6,7};

+        assertEquals("Assert invoke tataFloat[]", tota.tataFloats(h), h);

+        

+    }

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeTata(Tota tota) {

+        tota.tata(1,2);

+        tota.tata("tototototo");

+    }

+    

+    private void invokeTata1(Tota tota) {

+        assertEquals("Assert tata1", tota.tata1("foo"), "foo");

+        assertEquals("Assert tata1 - 2", tota.tata1(new char[] {'a','b','c'}), "abc");

+    }

+    

+    private void invokeTata5(Tota tota) {

+        assertEquals("Assert tata5 -1", tota.tata5("foo",1), "foo"+1);

+        assertEquals("Assert tata5 - 2", tota.tata5(new String[] {"a","b","c"}, 1), "31");

+        assertEquals("Assert tata5 - 3", tota.tata5("foo", new int[] {1,2,3}), "foo3");

+    }

+    

+    private void invokeAdd(Tota tota) {

+        assertEquals("Assert add", tota.add(1,1,1), 3);

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        invokeArrays(tota);

+        invokeStr(tota);

+        invokeTata(tota);

+        invokeTata1(tota);

+        invokeTata5(tota);

+        invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp1.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp1.java
new file mode 100644
index 0000000..95d64be
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp1.java
@@ -0,0 +1,337 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp1 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+	private ComponentFactory tataFactory2;

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-1");

+        Properties props2 = new Properties();

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            fail("Cannot create the instance : " + e.getMessage());

+        }

+         

+    }

+    

+    public void tearDown() {  

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        Integer tataStr = (Integer) props.get("tataStr");

+        Integer tataStrs = (Integer) props.get("tataStrs");

+        Integer tata_2 = (Integer) props.get("tata_2");

+        Integer tata_3 = (Integer) props.get("tata_3");

+        Integer tata1 = (Integer) props.get("tata1");

+        Integer tata1_1 = (Integer) props.get("tata1_1");

+        Integer tata5 = (Integer) props.get("tata5");

+        Integer tata5_1 = (Integer) props.get("tata5_1");

+        Integer tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 3", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 3", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 3", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 3", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 3", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 3", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 3", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 3", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 3", tata5_2.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 4", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        assertEquals("Assert tataStr - 4", tataStr.intValue(), 2);

+        assertEquals("Assert tataStrs - 4", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 4", tata_2.intValue(), 2);

+        assertEquals("Assert tata_3 - 4", tata_3.intValue(), 2);

+        assertEquals("Assert tata1 - 4", tata1.intValue(), 2);

+        assertEquals("Assert tata1_1 - 4", tata1_1.intValue(), 2);

+        assertEquals("Assert tata5 - 4", tata5.intValue(), 2);

+        assertEquals("Assert tata5_1 - 4", tata5_1.intValue(), 2);

+        assertEquals("Assert tata5_2 - 4", tata5_2.intValue(), 2);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 6", toto.intValue(), 3);

+        assertEquals("Assert toto_2 - 6", toto_2.intValue(), 3);

+        assertEquals("Assert toto_3 - 6", toto_3.intValue(), 3);

+        assertEquals("Assert toto_4 - 6", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 6", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 6", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 6", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 6", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 6", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 6", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 6", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 6", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 6", tata5_2.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), under.getInstanceName()));

+        

+        totoProv.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), under.getInstanceName()));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    private void invokeArrays(Tota tota) {

+        

+        int[] a = new int[] {1,2,3};

+        assertEquals("Assert invoke tataint[]", tota.tataInts(a), a);

+        

+        long[] b = new long[] {1,2,3};

+        assertEquals("Assert invoke tataLong[]", tota.tataLongs(b), b);

+        

+        double[] c = new double[] {1,2,3};

+        assertEquals("Assert invoke tataDouble[]", tota.tataDoubles(c), c);

+        

+        char[] d = new char[] {'a','b', 'c'};

+        assertEquals("Assert invoke tataChar[]", tota.tataChars(d), d);

+        

+        boolean[] e = new boolean[] {true, false};

+        assertEquals("Assert invoke tataBoolean[]", tota.tataBooleans(e), e);

+        

+        byte[] f = new byte[] {(byte) 1};

+        assertEquals("Assert invoke tataByte[]", tota.tataBytes(f), f);

+        

+        short[] g = new short[] {(short) 1};

+        assertEquals("Assert invoke tataShort[]", tota.tataShorts(g), g);

+        

+        float[] h = new float[] {5,6,7};

+        assertEquals("Assert invoke tataFloat[]", tota.tataFloats(h), h);

+        

+    }

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeTata(Tota tota) {

+        tota.tata(1,2);

+        tota.tata("tototototo");

+    }

+    

+    private void invokeTata1(Tota tota) {

+        assertEquals("Assert tata1", tota.tata1("foo"), "foo");

+        assertEquals("Assert tata1 - 2", tota.tata1(new char[] {'a','b','c'}), "abc");

+    }

+    

+    private void invokeTata5(Tota tota) {

+        assertEquals("Assert tata5 -1", tota.tata5("foo",1), "foo"+1);

+        assertEquals("Assert tata5 - 2", tota.tata5(new String[] {"a","b","c"}, 1), "31");

+        assertEquals("Assert tata5 - 3", tota.tata5("foo", new int[] {1,2,3}), "foo3");

+    }

+    

+    private void invokeAdd(Tota tota) {

+        assertEquals("Assert add", tota.add(1,1,1), 3);

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        invokeArrays(tota);

+        invokeStr(tota);

+        invokeTata(tota);

+        invokeTata1(tota);

+        invokeTata5(tota);

+        invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp2.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp2.java
new file mode 100644
index 0000000..763080f
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp2.java
@@ -0,0 +1,232 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp2 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+	private ComponentFactory tataFactory2;

+

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-2");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+         

+    }

+    

+    public void tearDown() { 

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        

+        invokeAll(tota);

+        

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 3 (" + toto_1.intValue() + ")", toto_1.intValue(), 1);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 4 ("+toto.intValue()+")", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4 ("+toto_2.intValue()+")", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 4", toto_1.intValue(), 3);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 6 ("+toto.intValue()+")", toto.intValue(), 3);

+        assertEquals("Assert toto_2 - 6 ("+toto_2.intValue()+")", toto_2.intValue(), 3);

+        assertEquals("Assert toto_3 - 6", toto_3.intValue(), 3);

+        assertEquals("Assert toto_4 - 6", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 6", toto_1.intValue(), 4);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        totoProv.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+        tota.toto1("foo2");

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        invokeToto(tota);

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp3.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp3.java
new file mode 100644
index 0000000..07ac5d3
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp3.java
@@ -0,0 +1,262 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp3 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+	private ComponentFactory tataFactory2;  

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-3");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+         

+    }

+    

+    public void tearDown() {  

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 3 (" + toto_1.intValue() + ")", toto_1.intValue(), 1);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 4 ("+toto.intValue()+")", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4 ("+toto_2.intValue()+")", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 4", toto_1.intValue(), 2);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Stop the factory

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        totoProv.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAllOpt(tota);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        tataFactory.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+        tota.toto1("foo");

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+    private void invokeAllOpt(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeTotoOpt(tota);

+    }

+    

+    private void invokeTotoOpt(Tota tota) {

+        try {

+            tota.toto();

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            assertEquals("Assert toto", tota.toto("foo"), "foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        

+        try {

+            tota.toto(1,2);

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            tota.toto1("foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp4.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp4.java
new file mode 100644
index 0000000..0d0f36c
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp4.java
@@ -0,0 +1,261 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp4 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+	private ComponentFactory tataFactory2;

+

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-4");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+         

+    }

+    

+    public void tearDown() {  

+    	tataFactory2.start();

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 3 (" + toto_1.intValue() + ")", toto_1.intValue(), 1);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 4 ("+toto.intValue()+")", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4 ("+toto_2.intValue()+")", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 4", toto_1.intValue(), 2);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Stop the factory

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        totoProv.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAllOpt(tota);

+        // Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        tataFactory.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+        tota.toto1("foo");

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+    private void invokeAllOpt(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeTotoOpt(tota);

+    }

+    

+    private void invokeTotoOpt(Tota tota) {

+        try {

+            tota.toto();

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            assertEquals("Assert toto", tota.toto("foo"), "foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        

+        try {

+            tota.toto(1,2);

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            tota.toto1("foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp5.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp5.java
new file mode 100644
index 0000000..7dd11f7
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp5.java
@@ -0,0 +1,265 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp5 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+	private ComponentFactory tataFactory2;

+

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-5");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+            fail("Cannot create an instance from comp-5 : " + e.getMessage());

+        }

+         

+    }

+    

+    public void tearDown() {    

+    	tataFactory2.start();

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 3 (" + toto_1.intValue() + ")", toto_1.intValue(), 1);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 4 ("+toto.intValue()+")", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4 ("+toto_2.intValue()+")", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 4", toto_1.intValue(), 3);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Stop the factory

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        totoProv.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAllOpt(tota);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        tataFactory.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+        tota.toto1("foo");

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+    private void invokeAllOpt(Tota tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+        invokeTotoOpt(tota);

+    }

+    

+    private void invokeTotoOpt(Tota tota) {

+        try {

+            tota.toto();

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            assertEquals("Assert toto", tota.toto("foo"), "foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        

+        try {

+            tota.toto(1,2);

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+        	tota.toto1("foo");

+        	fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp6.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp6.java
new file mode 100644
index 0000000..609c23c
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp6.java
@@ -0,0 +1,284 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tata;

+import org.apache.felix.ipojo.test.composite.service.Toto;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp6 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        

+        tataFactory.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-6");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+         

+    }

+    

+    public void tearDown() {       

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        ServiceReference refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        ServiceReference refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNull("Assert no toto service - 1", refToto);

+        assertNull("Assert no tata service - 1", refTata);

+

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2 ("+under.getState()+")", under.getState() == ComponentInstance.INVALID);

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNull("Assert no toto service - 2", refToto);

+        assertNull("Assert no tata service - 2", refTata);

+

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNotNull("Assert toto service - 3", refToto);

+        assertNotNull("Assert tata service - 3", refTata);

+        Toto toto = (Toto) context.getService(refToto);

+        Tata tata = (Tata) context.getService(refTata);

+ 

+        invokeAll(tata);

+        invokeToto(toto);

+ 

+        // Check toto

+        Properties props = toto.getProps();

+        Integer toto_0 = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 3 ("+toto_0.intValue()+")", toto_0.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 3 (" + toto_1.intValue() + ")", toto_1.intValue(), 1);

+        //Check tata

+        props = tata.getPropsTata();

+        Integer tata_0 = (Integer) props.get("tata");

+        assertEquals("Assert tata - 3", tata_0.intValue(), 1);

+

+        context.ungetService(refToto);

+        context.ungetService(refTata);

+        toto = null;

+        tata = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNotNull("Assert toto service - 4", refToto);

+        assertNotNull("Assert tata service - 4", refTata);

+        

+        toto = (Toto) context.getService(refToto);

+        tata = (Tata) context.getService(refTata);

+        invokeAll(tata);

+        invokeToto(toto);

+

+        // Check toto

+        props = toto.getProps();

+        toto_0 = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        toto_1 = (Integer) props.get("toto1");

+        assertEquals("Assert toto - 4 ("+toto_0.intValue()+")", toto_0.intValue(), 2);

+        assertEquals("Assert toto_2 - 4 ("+toto_2.intValue()+")", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert toto1 - 4", toto_1.intValue(), 3);

+        //Check tata

+        props = tata.getPropsTata();

+        tata_0 = (Integer) props.get("tata");

+        assertEquals("Assert tata - 4", tata_0.intValue(), 2);

+        context.ungetService(refToto);

+        context.ungetService(refTata);

+        toto = null;

+        tata = null;

+

+        // Stop the factory

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNull("Assert no toto service - 5", refToto);

+        assertNull("Assert no tata service - 5", refTata);

+ 

+        totoProv2.stop();

+        totoProv.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNotNull("Assert toto service - 6", refToto);

+        assertNotNull("Assert tata service - 6", refTata);

+        toto = (Toto) context.getService(refToto);

+        tata = (Tata) context.getService(refTata);

+ 

+        invokeAll(tata);

+        invokeTotoOpt(toto);

+        //  Check tata

+        props = tata.getPropsTata();

+        tata_0 = (Integer) props.get("tata");

+        assertEquals("Assert tata - 6", tata_0.intValue(), 1);

+        context.ungetService(refToto);

+        context.ungetService(refTata);

+        toto = null;

+        tata = null;

+ 

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        tataFactory.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        refToto = Utils.getServiceReferenceByName(context, Toto.class.getName(), "ff");

+        refTata = Utils.getServiceReferenceByName(context, Tata.class.getName(), "ff");

+        assertNull("Assert no toto service - 7", refToto);

+        assertNull("Assert no tata service - 7", refTata);

+        

+        under.dispose();

+        under = null;

+    }

+

+    private void invoke(Tata tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    

+    private void invokeStr(Tata tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeToto(Toto tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+        tota.toto1("foo");

+    }

+    

+    private void invokeAll(Tata tota) {

+        invoke(tota);

+        //invokeArrays(tota);

+        invokeStr(tota);

+        //invokeTata(tota);

+        //invokeTata1(tota);

+        //invokeTata5(tota);

+        //invokeAdd(tota);

+    }

+    

+    private void invokeTotoOpt(Toto tota) {

+        try {

+            tota.toto();

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+            assertEquals("Assert toto", tota.toto("foo"), "foo");

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        

+        try {

+            tota.toto(1,2);

+            fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+        

+        try {

+        	tota.toto1("foo");

+        	fail("UnsupportedOperationException expected");

+        } catch(UnsupportedOperationException e) { }

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp7.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp7.java
new file mode 100644
index 0000000..67a6c19
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp7.java
@@ -0,0 +1,333 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp7 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    private ComponentFactory tataFactory2;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-7");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        tataFactory.stop();

+         

+    }

+    

+    public void tearDown() {

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+    }

+    

+    public void testSimple() {

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 1);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        Integer tataStr = (Integer) props.get("tataStr");

+        Integer tataStrs = (Integer) props.get("tataStrs");

+        Integer tata_2 = (Integer) props.get("tata_2");

+        Integer tata_3 = (Integer) props.get("tata_3");

+        Integer tata1 = (Integer) props.get("tata1");

+        Integer tata1_1 = (Integer) props.get("tata1_1");

+        Integer tata5 = (Integer) props.get("tata5");

+        Integer tata5_1 = (Integer) props.get("tata5_1");

+        Integer tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 3", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 3", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 3", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 3", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 3", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 3", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 3", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 3", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 3", tata5_2.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 4", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 2);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        assertEquals("Assert tataStr - 4", tataStr.intValue(), 2);

+        assertEquals("Assert tataStrs - 4", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 4", tata_2.intValue(), 2);

+        assertEquals("Assert tata_3 - 4", tata_3.intValue(), 2);

+        assertEquals("Assert tata1 - 4", tata1.intValue(), 2);

+        assertEquals("Assert tata1_1 - 4", tata1_1.intValue(), 2);

+        assertEquals("Assert tata5 - 4", tata5.intValue(), 2);

+        assertEquals("Assert tata5_1 - 4", tata5_1.intValue(), 2);

+        assertEquals("Assert tata5_2 - 4", tata5_2.intValue(), 2);

+

+        context.ungetService(ref);

+        tota = null;

+        

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        assertEquals("Assert toto - 6", toto.intValue(), 3);

+        assertEquals("Assert toto_2 - 6", toto_2.intValue(), 3);

+        assertEquals("Assert toto_3 - 6", toto_3.intValue(), 3);

+        assertEquals("Assert toto_4 - 6", toto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 6", 1, tata.intValue());

+        assertEquals("Assert tataStr - 6", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 6", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 6", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 6", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 6", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 6", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 6", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 6", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 6", tata5_2.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        totoProv.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    private void invokeArrays(Tota tota) {

+        

+        int[] a = new int[] {1,2,3};

+        assertEquals("Assert invoke tataint[]", tota.tataInts(a), a);

+        

+        long[] b = new long[] {1,2,3};

+        assertEquals("Assert invoke tataLong[]", tota.tataLongs(b), b);

+        

+        double[] c = new double[] {1,2,3};

+        assertEquals("Assert invoke tataDouble[]", tota.tataDoubles(c), c);

+        

+        char[] d = new char[] {'a','b', 'c'};

+        assertEquals("Assert invoke tataChar[]", tota.tataChars(d), d);

+        

+        boolean[] e = new boolean[] {true, false};

+        assertEquals("Assert invoke tataBoolean[]", tota.tataBooleans(e), e);

+        

+        byte[] f = new byte[] {(byte) 1};

+        assertEquals("Assert invoke tataByte[]", tota.tataBytes(f), f);

+        

+        short[] g = new short[] {(short) 1};

+        assertEquals("Assert invoke tataShort[]", tota.tataShorts(g), g);

+        

+        float[] h = new float[] {5,6,7};

+        assertEquals("Assert invoke tataFloat[]", tota.tataFloats(h), h);

+        

+    }

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeTata(Tota tota) {

+        tota.tata(1,2);

+        tota.tata("tototototo");

+    }

+    

+    private void invokeTata1(Tota tota) {

+        assertEquals("Assert tata1", tota.tata1("foo"), "foo");

+        assertEquals("Assert tata1 - 2", tota.tata1(new char[] {'a','b','c'}), "abc");

+    }

+    

+    private void invokeTata5(Tota tota) {

+        assertEquals("Assert tata5 -1", tota.tata5("foo",1), "foo"+1);

+        assertEquals("Assert tata5 - 2", tota.tata5(new String[] {"a","b","c"}, 1), "31");

+        assertEquals("Assert tata5 - 3", tota.tata5("foo", new int[] {1,2,3}), "foo3");

+    }

+    

+    private void invokeAdd(Tota tota) {

+        assertEquals("Assert add", tota.add(1,1,1), 3);

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        invokeArrays(tota);

+        invokeStr(tota);

+        invokeTata(tota);

+        invokeTata1(tota);

+        invokeTata5(tota);

+        invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp8.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp8.java
new file mode 100644
index 0000000..f9ceb09
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/provides/TestComp8.java
@@ -0,0 +1,365 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.provides;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.component.TotoProvider;

+import org.apache.felix.ipojo.test.composite.component.TotoProviderGlue;

+import org.apache.felix.ipojo.test.composite.service.Tota;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestComp8 extends OSGiTestCase {

+

+    private ComponentFactory tataFactory;

+    private ComponentFactory totoFactory;

+    private ComponentFactory tataFactory2;

+    

+    private ComponentInstance totoProv, totoProv2;

+    private ComponentInstance under;

+    

+    public void setUp() {

+        tataFactory = (ComponentFactory) Utils.getFactoryByName(context, "tata");

+        totoFactory = (ComponentFactory) Utils.getFactoryByName(context, "toto");

+        tataFactory2 = (ComponentFactory) Utils.getFactoryByName(context, "comp-6");

+        tataFactory2.stop();

+        

+        Properties props = new Properties();

+        props.put("name", "toto provider");

+        try {

+            totoProv = totoFactory.createComponentInstance(props);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        Properties props3 = new Properties();

+        props3.put("name", "toto provider 2");

+        try {

+            totoProv2 = totoFactory.createComponentInstance(props3);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        

+        totoProv.stop();

+        totoProv2.stop();

+        

+        Factory factory = Utils.getFactoryByName(context, "comp-8");

+        Properties props2 = new Properties();

+        props2.put("name", "ff");

+        try {

+            under = factory.createComponentInstance(props2);

+        } catch(Exception e) {

+            e.printStackTrace();

+        }

+        tataFactory.stop();

+         

+    }

+    

+    public void tearDown() {

+        tataFactory.start();

+        totoProv.dispose();

+        totoProv = null;

+        totoProv2.dispose();

+        totoProv2 = null;

+        tataFactory2.start();

+        

+        // Reset counters

+        TotoProvider.toto = 0;

+        TotoProvider.toto_2 = 0;

+        TotoProvider.toto_3 = 0;

+        TotoProvider.toto_4 = 0;

+        TotoProvider.toto1 = 0;

+        TotoProviderGlue.toto = 0;

+        TotoProviderGlue.toto_2 = 0;

+        TotoProviderGlue.toto_3 = 0;

+        TotoProviderGlue.toto_4 = 0;

+        TotoProviderGlue.toto1 = 0;

+    }

+    

+    public void testSimple() {        

+        // Neither factory nor instance

+        assertTrue("Assert under state - 1", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 1", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the importer

+        totoProv.start();

+        assertTrue("Assert under state - 2", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 2", context.getServiceReference(Tota.class.getName()));

+        

+        // Start the factory

+        tataFactory.start();

+        assertTrue("Assert under state - 3", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 3", context.getServiceReference(Tota.class.getName()));

+        ServiceReference ref = context.getServiceReference(Tota.class.getName());

+        Tota tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        Properties props = tota.getProps();

+        Integer toto = (Integer) props.get("toto");

+        Integer toto_2 = (Integer) props.get("toto_2");

+        Integer toto_3 = (Integer) props.get("toto_3");

+        Integer toto_4 = (Integer) props.get("toto_4");

+        Integer gtoto = (Integer) props.get("gtoto");

+        Integer gtoto_2 = (Integer) props.get("gtoto_2");

+        Integer gtoto_3 = (Integer) props.get("gtoto_3");

+        Integer gtoto_4 = (Integer) props.get("gtoto_4");

+        assertEquals("Assert toto - 3 ("+toto.intValue()+")", toto.intValue(), 1);

+        assertEquals("Assert toto_2 - 3", toto_2.intValue(), 1);

+        assertEquals("Assert toto_3 - 3", toto_3.intValue(), 0);

+        assertEquals("Assert toto_4 - 3", toto_4.intValue(), 0);

+        assertEquals("Assert gtoto - 3 ("+gtoto.intValue()+")", gtoto.intValue(), 1);

+        assertEquals("Assert gtoto_2 - 3", gtoto_2.intValue(), 1);

+        assertEquals("Assert gtoto_3 - 3", gtoto_3.intValue(), 1);

+        assertEquals("Assert gtoto_4 - 3", gtoto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        Integer tata = (Integer) props.get("tata");

+        Integer tataStr = (Integer) props.get("tataStr");

+        Integer tataStrs = (Integer) props.get("tataStrs");

+        Integer tata_2 = (Integer) props.get("tata_2");

+        Integer tata_3 = (Integer) props.get("tata_3");

+        Integer tata1 = (Integer) props.get("tata1");

+        Integer tata1_1 = (Integer) props.get("tata1_1");

+        Integer tata5 = (Integer) props.get("tata5");

+        Integer tata5_1 = (Integer) props.get("tata5_1");

+        Integer tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 3", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 3", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 3", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 3", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 3", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 3", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 3", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 3", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 3", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 3", tata5_2.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Start a second import

+        totoProv2.start();

+        assertTrue("Assert under state - 4", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 4", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        gtoto = (Integer) props.get("gtoto");

+        gtoto_2 = (Integer) props.get("gtoto_2");

+        gtoto_3 = (Integer) props.get("gtoto_3");

+        gtoto_4 = (Integer) props.get("gtoto_4");

+        assertEquals("Assert toto - 4", toto.intValue(), 2);

+        assertEquals("Assert toto_2 - 4", toto_2.intValue(), 2);

+        assertEquals("Assert toto_3 - 4", toto_3.intValue(), 0);

+        assertEquals("Assert toto_4 - 4", toto_4.intValue(), 0);

+        assertEquals("Assert gtoto - 4 ("+gtoto.intValue()+")", gtoto.intValue(), 2);

+        assertEquals("Assert gtoto_2 - 4", gtoto_2.intValue(), 2);

+        assertEquals("Assert gtoto_3 - 4", gtoto_3.intValue(), 2);

+        assertEquals("Assert gtoto_4 - 4", gtoto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 4", tata.intValue(), 2);

+        assertEquals("Assert tataStr - 4", tataStr.intValue(), 2);

+        assertEquals("Assert tataStrs - 4", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 4", tata_2.intValue(), 2);

+        assertEquals("Assert tata_3 - 4", tata_3.intValue(), 2);

+        assertEquals("Assert tata1 - 4", tata1.intValue(), 2);

+        assertEquals("Assert tata1_1 - 4", tata1_1.intValue(), 2);

+        assertEquals("Assert tata5 - 4", tata5.intValue(), 2);

+        assertEquals("Assert tata5_1 - 4", tata5_1.intValue(), 2);

+        assertEquals("Assert tata5_2 - 4", tata5_2.intValue(), 2);

+

+        context.ungetService(ref);

+        tota = null;

+        

+        tataFactory.stop();

+        assertTrue("Assert under state - 5", under.getState() == ComponentInstance.INVALID);

+        assertNull("Assert no tota service - 5", context.getServiceReference(Tota.class.getName()));

+        

+        totoProv2.stop();

+        tataFactory.start();

+        assertTrue("Assert under state - 6", under.getState() == ComponentInstance.VALID);

+        assertNotNull("Assert tota service - 6", context.getServiceReference(Tota.class.getName()));

+        ref = context.getServiceReference(Tota.class.getName());

+        tota = (Tota) context.getService(ref);

+        invokeAll(tota);

+        // Check toto

+        props = tota.getProps();

+        toto = (Integer) props.get("toto");

+        toto_2 = (Integer) props.get("toto_2");

+        toto_3 = (Integer) props.get("toto_3");

+        toto_4 = (Integer) props.get("toto_4");

+        gtoto = (Integer) props.get("gtoto");

+        gtoto_2 = (Integer) props.get("gtoto_2");

+        gtoto_3 = (Integer) props.get("gtoto_3");

+        gtoto_4 = (Integer) props.get("gtoto_4");

+        assertEquals("Assert toto - 6", toto.intValue(), 3);

+        assertEquals("Assert toto_2 - 6", toto_2.intValue(), 3);

+        assertEquals("Assert toto_3 - 6", toto_3.intValue(), 0);

+        assertEquals("Assert toto_4 - 6", toto_4.intValue(), 0);

+        assertEquals("Assert gtoto - 6 ("+gtoto.intValue()+")", gtoto.intValue(), 3);

+        assertEquals("Assert gtoto_2 - 6", gtoto_2.intValue(), 3);

+        assertEquals("Assert gtoto_3 - 6", gtoto_3.intValue(), 3);

+        assertEquals("Assert gtoto_4 - 6", gtoto_4.intValue(), 0);

+        //Check tata

+        props = tota.getPropsTata();

+        tata = (Integer) props.get("tata");

+        tataStr = (Integer) props.get("tataStr");

+        tataStrs = (Integer) props.get("tataStrs");

+        tata_2 = (Integer) props.get("tata_2");

+        tata_3 = (Integer) props.get("tata_3");

+        tata1 = (Integer) props.get("tata1");

+        tata1_1 = (Integer) props.get("tata1_1");

+        tata5 = (Integer) props.get("tata5");

+        tata5_1 = (Integer) props.get("tata5_1");

+        tata5_2 = (Integer) props.get("tata5_2");

+        assertEquals("Assert tata - 6", tata.intValue(), 1);

+        assertEquals("Assert tataStr - 6", tataStr.intValue(), 1);

+        assertEquals("Assert tataStrs - 6", tataStrs.intValue(), 0);

+        assertEquals("Assert tata_2 - 6", tata_2.intValue(), 1);

+        assertEquals("Assert tata_3 - 6", tata_3.intValue(), 1);

+        assertEquals("Assert tata1 - 6", tata1.intValue(), 1);

+        assertEquals("Assert tata1_1 - 6", tata1_1.intValue(), 1);

+        assertEquals("Assert tata5 - 6", tata5.intValue(), 1);

+        assertEquals("Assert tata5_1 - 6", tata5_1.intValue(), 1);

+        assertEquals("Assert tata5_2 - 6", tata5_2.intValue(), 1);

+        context.ungetService(ref);

+        tota = null;

+        

+        // Is arch exposed

+        assertNotNull("Test arch", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        

+        totoProv.stop();

+        

+        assertTrue("Assert under state - 7", under.getState() == ComponentInstance.INVALID);

+        assertNotNull("Test arch-2", Utils.getServiceReferenceByName(context, Architecture.class.getName(), "ff"));

+        assertNull("Assert no tota service - 7", context.getServiceReference(Tota.class.getName()));

+        

+        under.dispose();

+        under = null;

+    }

+

+

+

+    private void invoke(Tota tota) {

+        tota.tata();

+        

+        assertEquals("Assert invoke tataint", tota.tataInt(2), 2);

+        assertEquals("Assert invoke tataLong", tota.tataLong(2), 2);

+        assertEquals("Assert invoke tataDouble", tota.tataDouble(2), 2);

+        assertEquals("Assert invoke tataChar", tota.tataChar('a'), 'a');

+        assertTrue("Assert invoke tataBoolean", tota.tataBoolean(true));

+        assertEquals("Assert invoke tataByte", tota.tataByte((byte)2), 2);

+        assertEquals("Assert invoke tataShort", tota.tataShort((short)5), 5);

+        assertEquals("Assert invoke tataFloat", tota.tataFloat(5), 5);

+        

+    }

+    

+    private void invokeArrays(Tota tota) {

+        

+        int[] a = new int[] {1,2,3};

+        assertEquals("Assert invoke tataint[]", tota.tataInts(a), a);

+        

+        long[] b = new long[] {1,2,3};

+        assertEquals("Assert invoke tataLong[]", tota.tataLongs(b), b);

+        

+        double[] c = new double[] {1,2,3};

+        assertEquals("Assert invoke tataDouble[]", tota.tataDoubles(c), c);

+        

+        char[] d = new char[] {'a','b', 'c'};

+        assertEquals("Assert invoke tataChar[]", tota.tataChars(d), d);

+        

+        boolean[] e = new boolean[] {true, false};

+        assertEquals("Assert invoke tataBoolean[]", tota.tataBooleans(e), e);

+        

+        byte[] f = new byte[] {(byte) 1};

+        assertEquals("Assert invoke tataByte[]", tota.tataBytes(f), f);

+        

+        short[] g = new short[] {(short) 1};

+        assertEquals("Assert invoke tataShort[]", tota.tataShorts(g), g);

+        

+        float[] h = new float[] {5,6,7};

+        assertEquals("Assert invoke tataFloat[]", tota.tataFloats(h), h);

+        

+    }

+    

+    private void invokeStr(Tota tota) {

+        tota.tataStr();

+    }

+    

+    private void invokeTata(Tota tota) {

+        tota.tata(1,2);

+        tota.tata("tototototo");

+    }

+    

+    private void invokeTata1(Tota tota) {

+        assertEquals("Assert tata1", tota.tata1("foo"), "foo");

+        assertEquals("Assert tata1 - 2", tota.tata1(new char[] {'a','b','c'}), "abc");

+    }

+    

+    private void invokeTata5(Tota tota) {

+        assertEquals("Assert tata5 -1", tota.tata5("foo",1), "foo"+1);

+        assertEquals("Assert tata5 - 2", tota.tata5(new String[] {"a","b","c"}, 1), "31");

+        assertEquals("Assert tata5 - 3", tota.tata5("foo", new int[] {1,2,3}), "foo3");

+    }

+    

+    private void invokeAdd(Tota tota) {

+        assertEquals("Assert add", tota.add(1,1,1), 3);

+    }

+    

+    private void invokeToto(Tota tota) {

+        tota.toto();

+        assertEquals("Assert toto", tota.toto("foo"), "foo");

+        tota.toto(1,2);

+    }

+    

+    private void invokeAll(Tota tota) {

+        invoke(tota);

+        invokeArrays(tota);

+        invokeStr(tota);

+        invokeTata(tota);

+        invokeTata1(tota);

+        invokeTata5(tota);

+        invokeAdd(tota);

+        invokeToto(tota);

+    }

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/A123/CheckService2.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/A123/CheckService2.java
new file mode 100644
index 0000000..1a745a9
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/A123/CheckService2.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.service.A123;

+

+public interface CheckService2 {

+	

+	public boolean check();

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tata.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tata.java
new file mode 100644
index 0000000..04fe33d
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tata.java
@@ -0,0 +1,62 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.service;

+

+import java.util.Properties;

+

+public interface Tata {

+    

+    public Properties getPropsTata();

+    

+    public void tata();

+    

+    public int tataInt(int i);

+    public long tataLong(long l);

+    public double tataDouble(double d);

+    public char tataChar(char c);

+    public boolean tataBoolean(boolean b);

+    public short tataShort(short s);

+    public float tataFloat(float f);

+    public byte tataByte(byte b);

+    

+    public int[] tataInts(int[] its);

+    public long[] tataLongs(long[] l);

+    public double[] tataDoubles(double[] d);

+    public char[] tataChars(char[] c);

+    public boolean[] tataBooleans(boolean[] b);

+    public short[] tataShorts(short[] s);

+    public float[] tataFloats(float[] f);

+    public byte[] tataBytes(byte[] b);

+    

+    public String tataStr();

+    public String[] tataStrs();

+    

+    public void tata(int i, int j);

+    public void tata(String s);

+    

+    public String tata1(String a);

+    public String tata1(char[] a);

+    

+    public String tata5(String a, int i);

+    public String tata5(String[] a, int i);

+    public String tata5(String a, int[] i);

+    

+    public long add(int i, int j, int k);

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tota.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tota.java
new file mode 100644
index 0000000..f7481a4
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Tota.java
@@ -0,0 +1,78 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.service;

+

+import java.util.Properties;

+

+public interface Tota {

+    

+    public static final String specification="specification { " +

+    		"requires { " +

+    		    "$specification=\"org.apache.felix.ipojo.test.composite.service.Toto\" " +

+    		    "$optional=\"true\" " +

+    		    "$aggregate=\"true\" " +

+    		    "$type=\"service\" " +

+    		"} }"; 

+    

+    public Properties getProps() throws UnsupportedOperationException;;

+    public Properties getPropsTata();

+    

+    public void tata();

+    

+    public int tataInt(int i);

+    public long tataLong(long l);

+    public double tataDouble(double d);

+    public char tataChar(char c);

+    public boolean tataBoolean(boolean b);

+    public short tataShort(short s);

+    public float tataFloat(float f);

+    public byte tataByte(byte b);

+    

+    public int[] tataInts(int[] its);

+    public long[] tataLongs(long[] l);

+    public double[] tataDoubles(double[] d);

+    public char[] tataChars(char[] c);

+    public boolean[] tataBooleans(boolean[] b);

+    public short[] tataShorts(short[] s);

+    public float[] tataFloats(float[] f);

+    public byte[] tataBytes(byte[] b);

+    

+    public String tataStr();

+    public String[] tataStrs();

+    

+    public void tata(int i, int j);

+    public void tata(String s);

+    

+    public String tata1(String a);

+    public String tata1(char[] a);

+    

+    public String tata5(String a, int i);

+    public String tata5(String[] a, int i);

+    public String tata5(String a, int[] i);

+    

+    public long add(int i, int j, int k);

+    

+    public void toto() throws UnsupportedOperationException;    

+    public void toto(int i, int j) throws UnsupportedOperationException;

+    public String toto(String a) throws UnsupportedOperationException;

+    

+    public void toto1(String j) throws UnsupportedOperationException;

+    

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Toto.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Toto.java
new file mode 100644
index 0000000..edf6c10
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/service/Toto.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.service;

+

+import java.util.Properties;

+

+public interface Toto {

+    

+    public Properties getProps();

+    

+    public void toto();    

+    public void toto(int i, int j);

+    public String toto(String a);

+    public String toto(String[] a);

+    

+    public void toto1(String j);

+    

+    public int count();

+

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/test/CompositeTest.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/test/CompositeTest.java
new file mode 100644
index 0000000..9f7c6c4
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/test/CompositeTest.java
@@ -0,0 +1,180 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.test;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.composite.util.Utils;

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class CompositeTest extends OSGiTestCase {

+	

+	public void testAPI() {

+		Factory fact1 = Utils.getFactoryByName(context, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty-1");

+		ComponentInstance empty = null;

+		try {

+			empty = fact1.createComponentInstance(p);

+		} catch(Exception e) {

+			e.printStackTrace();

+			fail(e.getMessage());

+		}

+		

+		ServiceContext sc = Utils.getServiceContext(empty);

+		

+		Factory fact2 = Utils.getFactoryByName(context, "composite.test.2");

+		Properties props2 = new Properties();

+		props2.put("name", "2"); // 2

+		Factory fact3 = Utils.getFactoryByName(context, "composite.test.3");

+		Properties props3 = new Properties();

+		props3.put("name", "3");

+		ComponentInstance comp2 = null;

+		ComponentInstance comp3 = null;

+		try {

+			comp2 = fact2.createComponentInstance(props2, sc);

+			comp3 = fact3.createComponentInstance(props3, sc);

+		} catch(Throwable e) {

+		    e.printStackTrace();

+		    fail(e.getMessage());

+		}

+		

+		assertTrue("Test comp3", comp3.getState() == ComponentInstance.VALID);

+		assertTrue("Test comp2", comp2.getState() == ComponentInstance.VALID);

+		

+		ServiceReference ref = null;

+

+		ref = Utils.getServiceReferenceByName(sc, CheckService.class.getName(), "2"); // 2

+

+		assertNotNull("Check ref", ref);

+		CheckService cs = (CheckService) sc.getService(ref);

+		assertTrue("Check invoke", cs.check());

+		

+		comp3.dispose();

+		comp2.dispose();

+		empty.dispose();

+	}

+	

+	public void testInstantiator() {

+		String type = "composite.instantiator";

+		Factory fact = Utils.getFactoryByName(context, type);

+		ComponentInstance ci = null;

+		Properties p = new Properties();

+		p.put("name", "mon_coeur");

+		try {

+			ci = fact.createComponentInstance(p);

+		} catch(Exception e) {

+			e.printStackTrace();

+		}

+				

+		assertTrue("Check ci", ci.getState() == ComponentInstance.VALID);

+		ServiceReference ref = Utils.getServiceReferenceByName(context, BazService.class.getName(), "mon_coeur");

+		assertNotNull("Check ref",ref);

+		BazService bs = (BazService) context.getService(ref);

+		assertTrue("Check invocation", bs.foo());

+		context.ungetService(ref);

+		ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "mon_coeur");

+		assertNotNull("Check ref 2 ",ref);

+		FooService fs = (FooService) context.getService(ref);

+		assertTrue("Check invocation", fs.foo());

+		context.ungetService(ref);

+		ci.dispose();

+	}

+	

+	public void testAPI2() {

+		Factory fact1 = Utils.getFactoryByName(context, "composite.empty");

+		Properties p = new Properties();

+		p.put("name", "empty-2");

+		ComponentInstance empty = null;

+		try {

+			empty = fact1.createComponentInstance(p);

+		} catch(Exception e) {

+			e.printStackTrace();

+		}

+		

+		ServiceContext sc = Utils.getServiceContext(empty);

+		

+		Factory fact2 = Utils.getFactoryByName(sc, "composite.test.2");

+		Properties props2 = new Properties();

+		props2.put("name", "4");

+		Factory fact3 = Utils.getFactoryByName(sc, "composite.test.3");

+		Properties props3 = new Properties();

+		props3.put("name", "5");

+		ComponentInstance comp2 = null;

+		ComponentInstance comp3 = null;

+		try {

+			comp2 = fact2.createComponentInstance(props2, sc);

+			comp3 = fact3.createComponentInstance(props3, sc);

+		} catch(Exception e) {

+			e.printStackTrace();

+		}

+		

+		assertTrue("Test comp3", comp3.getState() == ComponentInstance.VALID);

+		assertTrue("Test comp2", comp2.getState() == ComponentInstance.VALID);

+		

+		ServiceReference ref = null;

+

+		ref = Utils.getServiceReferenceByName(sc, CheckService.class.getName(), "4");

+

+		assertNotNull("Check ref", ref);

+		CheckService cs = (CheckService) sc.getService(ref);

+		assertTrue("Check invoke", cs.check());

+		

+		comp3.dispose();

+		comp2.dispose();

+		empty.dispose();

+	}

+

+	

+	public void testApplication() {

+		Factory factory = Utils.getFactoryByName(context, "composite.test.1");

+		ComponentInstance ci = null;

+		Properties props = new Properties();

+		props.put("name", "Test");

+		try {

+			ci = factory.createComponentInstance(props);

+		} catch(Exception e) {

+			fail("Cannot instantiate Test " + e.getMessage());

+		}

+		

+		assertTrue("Check ci state", ci.getState() == ComponentInstance.VALID );

+		

+		ServiceReference[] refs = null;

+		try {

+			refs = context.getServiceReferences(CheckService.class.getName(), "(instance.name=Test)");

+		} catch (InvalidSyntaxException e) {

+			fail("Invalid filter : " + e.getMessage());

+		}

+		assertNotNull("Check refs not null", refs);

+		CheckService cs = (CheckService) context.getService(refs[0]);

+		

+		assertTrue("Check invocation", cs.check());

+		ci.dispose();

+		

+	}

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/util/Utils.java b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/util/Utils.java
new file mode 100644
index 0000000..ea67fee
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/java/org/apache/felix/ipojo/test/composite/util/Utils.java
@@ -0,0 +1,288 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.composite.util;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.Handler;

+import org.apache.felix.ipojo.HandlerFactory;

+import org.apache.felix.ipojo.ServiceContext;

+import org.apache.felix.ipojo.composite.CompositeManager;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+public class Utils {

+

+    public static Factory getFactoryByName(BundleContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(factory.name=" + factoryName + ")");

+            if (refs == null) {

+                System.err.println("Cannot get the factory " + factoryName);

+                return null;

+            }

+            return ((Factory) bc.getService(refs[0]));

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static HandlerFactory getHandlerFactoryByName(BundleContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(" + Handler.HANDLER_NAME_PROPERTY + "=" + factoryName + ")");

+            if (refs == null) {

+                System.err.println("Cannot get the factory " + factoryName);

+                return null;

+            }

+            return (HandlerFactory) bc.getService(refs[0]);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static ComponentInstance getComponentInstance(BundleContext bc, String factoryName, Dictionary configuration) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) {

+            System.err.println("Factory " + factoryName + " not found");

+            return null;

+        }

+

+        // if(fact.isAcceptable(configuration)) {

+        try {

+            return fact.createComponentInstance(configuration);

+        } catch (Exception e) {

+            System.err.println("Cannot create the instance from " + factoryName + " : " + e.getMessage());

+            e.printStackTrace();

+            return null;

+        }

+        // }

+        // else {

+        // System.err.println("Configuration not accepted by : " + factoryName);

+        // return null;

+        // }

+    }

+

+    public static ComponentInstance getComponentInstanceByName(BundleContext bc, String factoryName, String name) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) {

+            System.err.println("Factory " + factoryName + " not found");

+            return null;

+        }

+

+        try {

+            Properties props = new Properties();

+            props.put("name", name);

+            return fact.createComponentInstance(props);

+        } catch (Exception e) {

+            System.err.println("Cannot create the instance from " + factoryName + " : " + e.getMessage());

+            e.printStackTrace();

+            return null;

+        }

+    }

+

+    public static ServiceReference[] getServiceReferences(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return new ServiceReference[0];

+        } else {

+            return refs;

+        }

+    }

+

+    public static ServiceReference getServiceReference(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static ServiceReference getServiceReferenceByName(BundleContext bc, String itf, String name) {

+        ServiceReference[] refs = null;

+        String filter = null;

+        if (itf.equals(Factory.class.getName()) || itf.equals(ManagedServiceFactory.class.getName())) {

+            filter = "(" + "factory.name" + "=" + name + ")";

+        } else {

+            filter = "(" + "instance.name" + "=" + name + ")";

+        }

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static Object getServiceObject(BundleContext bc, String itf, String filter) {

+        ServiceReference ref = getServiceReference(bc, itf, filter);

+        if (ref != null) {

+            return bc.getService(ref);

+        } else {

+            return null;

+        }

+    }

+

+    public static Object[] getServiceObjects(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = getServiceReferences(bc, itf, filter);

+        if (refs != null) {

+            Object[] list = new Object[refs.length];

+            for (int i = 0; i < refs.length; i++) {

+                list[i] = bc.getService(refs[i]);

+            }

+            return list;

+        } else {

+            return new Object[0];

+        }

+    }

+

+    public static ServiceContext getServiceContext(ComponentInstance ci) {

+        if (ci instanceof CompositeManager) {

+            return ((CompositeManager) ci).getServiceContext();

+        } else {

+            throw new RuntimeException("Cannot get the service context from a non composite instance");

+        }

+    }

+

+    public static Factory getFactoryByName(ServiceContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(factory.name=" + factoryName + ")");

+            if (refs == null) { return null; }

+            return ((Factory) bc.getService(refs[0]));

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static ComponentInstance getComponentInstance(ServiceContext bc, String factoryName, Dictionary configuration) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) { return null; }

+

+        if (fact.isAcceptable(configuration)) {

+            try {

+                return fact.createComponentInstance(configuration);

+            } catch (Exception e) {

+                System.err.println(e.getMessage());

+                e.printStackTrace();

+                return null;

+            }

+        } else {

+            System.err.println("Configuration not accepted by : " + factoryName);

+            return null;

+        }

+    }

+

+    public static ServiceReference[] getServiceReferences(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return new ServiceReference[0];

+        } else {

+            return refs;

+        }

+    }

+

+    public static ServiceReference getServiceReference(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static ServiceReference getServiceReferenceByName(ServiceContext bc, String itf, String name) {

+        ServiceReference[] refs = null;

+        String filter = null;

+        if (itf.equals(Factory.class.getName()) || itf.equals(ManagedServiceFactory.class.getName())) {

+            filter = "(" + "factory.name" + "=" + name + ")";

+        } else {

+            filter = "(" + "instance.name" + "=" + name + ")";

+        }

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static Object getServiceObject(ServiceContext bc, String itf, String filter) {

+        ServiceReference ref = getServiceReference(bc, itf, filter);

+        if (ref != null) {

+            return bc.getService(ref);

+        } else {

+            return null;

+        }

+    }

+

+    public static Object[] getServiceObjects(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = getServiceReferences(bc, itf, filter);

+        if (refs != null) {

+            Object[] list = new Object[refs.length];

+            for (int i = 0; i < refs.length; i++) {

+                list[i] = bc.getService(refs[i]);

+            }

+            return list;

+        } else {

+            return new Object[0];

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.composite/src/main/resources/metadata.xml b/ipojo/tests/tests.composite/src/main/resources/metadata.xml
new file mode 100644
index 0000000..2357580
--- /dev/null
+++ b/ipojo/tests/tests.composite/src/main/resources/metadata.xml
@@ -0,0 +1,221 @@
+<ipojo xmlns:cs="org.apache.felix.ipojo.test.composite.handler.CheckServiceHandler">

+	<!--  Composite -->

+	<composite name="composite.empty" factory="true" architecture="true">

+	</composite>

+	

+	<composite name="composite.bar.1" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BarService"/>

+	</composite>

+	

+	<composite name="composite.bar.2" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BarService" aggregate="true"/>

+	</composite>

+	

+	<composite name="composite.bar.3" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BarService" optional="true"/>

+	</composite>

+	

+	<composite name="composite.bar.4" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" aggregate="true" optional="true"/>

+	</composite>

+	

+	<composite name="composite.bar.5-accept" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.FooService">

+			<property name="boolean" value="true"/>

+			<property name="string" value="foo"/>

+			<property name="strAprop" value="{foo, bar, baz}"/>

+			<property name="int" value="5"/>

+		</subservice>

+	</composite>

+	

+	<composite name="composite.bar.5-refuse1" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BarService">

+			<property name="foo" value="bar"/>

+			<property name="boolean" value="true"/>

+			<property name="string" value="foo"/>

+			<property name="strAprop" value="{foo, bar, baz}"/>

+			<property name="int" value="5"/>

+		</subservice>

+	</composite>

+	

+	<composite name="composite.bar.5-refuse2" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BarService">

+			<property name="string" value="foo"/>

+			<property name="strAprop" value="{foo, bar, baz}"/>

+		</subservice>

+	</composite>

+	

+	<composite name="composite.inst.1" factory="true" architecture="true">

+		<instance component="FooProviderType-1" /> <!-- name="FooProv"  -->

+		<instance component="FooProviderType-Dyn2">

+			<property name="boolean" value="true"/>

+			<property name="string" value="foo"/>

+			<property name="strAProp" value="{a,b,c}"/>

+		</instance>

+	</composite>

+	

+	<composite name="composite.requires.1" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" scope="composite"/>

+	</composite>

+	

+	<composite name="composite.requires.2" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" aggregate="true" scope="composite"/>

+	</composite>

+	

+	<composite name="composite.requires.3" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" optional="true" scope="composite"/>

+	</composite>

+	

+	<composite name="composite.requires.4" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" optional="true" aggregate="true" scope="composite"/>

+	</composite>

+	

+	<composite name="composite.requires.5" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.FooService" filter="(&amp;(int=2)(long=40))" scope="composite"/>

+	</composite>

+	

+	<component className="org.apache.felix.ipojo.test.composite.component.BazProviderType1" factory="BazProviderType" scope="composite">

+		<provides/>

+	</component>

+	

+	<composite name="composite.export.1" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true" optional="true" filter="(!(instance.name=export))" scope="composite"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService"/>

+	</composite>

+	

+	<composite name="composite.export.2" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" scope="composite" aggregate="true" optional="true" filter="(!(instance.name=export))"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" optional="true"/>

+	</composite>

+	

+	<composite name="composite.export.3" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" scope="composite" aggregate="true" optional="true" filter="(!(instance.name=export))"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true"/>

+	</composite>

+	

+	<composite name="composite.export.4" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true" optional="true" filter="(!(instance.name=export))" scope="composite"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true" optional="true"/>

+	</composite>

+	

+	<composite name="composite.export.5" architecture="true">

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true" optional="true" filter="(!(instance.name=export))" scope="composite"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" filter="(instance.name=foo1)"/>

+	</composite>

+	

+	<component className="org.apache.felix.ipojo.test.composite.component.Baz2CheckProvider" factory="Baz2CheckProvider" architecture="true">

+		<requires field="fs" scope="composite"/>

+		<provides/>

+	</component>

+

+	<composite name="composite.test.3" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" aggregate="true" filter="(factory.name=BazProviderType)"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService"/>

+	</composite>

+	

+	<composite name="composite.test.2" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.CheckService" filter="(factory.name=Baz2CheckProvider)"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.CheckService"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" scope="composite"/>

+	</composite>

+	

+	<composite name="composite.test.1" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" filter="(factory.name=composite.test.3)" />

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.CheckService" filter="(factory.name=composite.test.2)"/>

+		<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.CheckService"/>

+	</composite>

+

+	<composite name="composite.instantiator" architecture="true">

+				<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.BazService" filter="(factory.name=composite.test.3)"/>

+				<subservice action="instantiate" specification="org.apache.felix.ipojo.test.scenarios.service.FooService"/>

+				<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.BazService"/>

+				<provides action="export" specification="org.apache.felix.ipojo.test.scenarios.service.FooService"/>

+	</composite>

+

+	<!-- Test composition provides -->

+	<component classname="org.apache.felix.ipojo.test.composite.component.TataProvider" factory="tata">

+		<provides/>

+	</component>

+	

+	<component classname="org.apache.felix.ipojo.test.composite.component.TotoProvider" factory="toto" architecture="true">

+		<provides/>

+	</component>

+	

+	<component classname="org.apache.felix.ipojo.test.composite.component.TotoProviderGlue" factory="totoglue">

+		<requires field="m_toto" scope="composite"/>

+	</component>

+	

+	<composite name="comp-0" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota"/>

+	</composite>

+	

+	<composite name="comp-1" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota">

+			<delegation method="tataInt" policy="One"/>

+			<delegation method="toto1" policy="All"/>

+		</provides>

+	</composite>

+

+	<composite name="comp-2" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata" aggregate="true"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto" aggregate="true"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota">

+			<delegation method="tataInt" policy="One"/>

+			<delegation method="toto1" policy="All"/>

+		</provides>

+	</composite>	

+	

+	<composite name="comp-3" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto" optional="true"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota">

+		</provides>

+	</composite>

+	

+	<composite name="comp-4" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto" optional="true"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota">

+			<delegation method="tataInt" policy="One"/>

+			<delegation method="toto1" policy="All"/>

+		</provides>

+	</composite>		

+	

+	<composite name="comp-5" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata" aggregate="true"/>

+		<!-- <subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto" aggregate ="true" optional="true"/> -->

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota">

+			<delegation method="tataInt" policy="One"/>

+			<delegation method="toto1" policy="All"/>

+		</provides>

+	</composite>	

+	

+	<composite name="comp-6" architecture="true">

+		<subservice action="instantiate" specification="org.apache.felix.ipojo.test.composite.service.Tata" aggregate="true"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto" aggregate="true" optional="true"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Toto">

+			<delegation method="toto1" policy="All"/>

+		</provides>

+ 		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tata">

+			<delegation method="tataInt" policy="One"/>

+		</provides>

+	</composite>

+	

+	<composite name="comp-7" architecture="true">

+		<instance component="tata"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota"/>

+	</composite>

+	

+	<composite name="comp-8" architecture="true">

+		<instance component="tata"/>

+		<instance component="totoglue"/>

+		<subservice action="import" specification="org.apache.felix.ipojo.test.composite.service.Toto"/>

+		<provides action="implement" specification="org.apache.felix.ipojo.test.composite.service.Tota"/>

+	</composite>

+	

+</ipojo>

diff --git a/ipojo/tests/tests.core/pom.xml b/ipojo/tests/tests.core/pom.xml
new file mode 100644
index 0000000..8b95285
--- /dev/null
+++ b/ipojo/tests/tests.core/pom.xml
@@ -0,0 +1,111 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<groupId>ipojo.tests</groupId>

+		<artifactId>ipojo.tests</artifactId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>iPOJO Test Suite</name>

+	<artifactId>tests.core</artifactId>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.composite</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>3.8.1</version>

+		</dependency>

+		<dependency>

+			<groupId>ipojo.examples</groupId>

+			<artifactId>org.apache.felix.ipojo.junit4osgi</artifactId>

+			<version>0.7.6-SNAPSHOT</version>

+		</dependency>

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.0</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Export-Package>

+							org.apache.felix.ipojo.test.scenarios.service

+						</Export-Package>

+						<Bundle-SymbolicName>

+							${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Private-Package>

+							org.apache.felix.ipojo.test*

+						</Private-Package>

+						<Test-Suite>

+							org.apache.felix.ipojo.test.IPOJOTestSuite

+						</Test-Suite>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>0.7.6-SNAPSHOT</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<ignoreAnnotations>true</ignoreAnnotations>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-compiler-plugin</artifactId>

+				<configuration>

+					<source>1.5</source>

+					<target>1.5</target>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/IPOJOTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/IPOJOTestSuite.java
new file mode 100644
index 0000000..b9fbeb9
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/IPOJOTestSuite.java
@@ -0,0 +1,55 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.apache.felix.ipojo.test.scenarios.architecture.ArchitectureTestSuite;

+import org.apache.felix.ipojo.test.scenarios.bad.BadTestSuite;

+import org.apache.felix.ipojo.test.scenarios.configuration.ConfigurationTestSuite;

+import org.apache.felix.ipojo.test.scenarios.controller.LifeCycleControllerTestSuite;

+import org.apache.felix.ipojo.test.scenarios.core.CoreTestSuite;

+import org.apache.felix.ipojo.test.scenarios.dependency.DependencyTestSuite;

+import org.apache.felix.ipojo.test.scenarios.factory.FactoryTestSuite;

+import org.apache.felix.ipojo.test.scenarios.handler.ExternalHandlerTestSuite;

+import org.apache.felix.ipojo.test.scenarios.lifecycle.LifeCycleCallbackTest;

+import org.apache.felix.ipojo.test.scenarios.manipulation.ManipulationTestSuite;

+import org.apache.felix.ipojo.test.scenarios.service.providing.ProvidedServiceTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class IPOJOTestSuite {

+    

+    public static Test suite(BundleContext bc) {

+        OSGiTestSuite ots = new OSGiTestSuite("IPojo Core Test Suite", bc);

+        ots.addTest(ManipulationTestSuite.suite(bc));

+        ots.addTest(CoreTestSuite.suite(bc));

+        ots.addTest(FactoryTestSuite.suite(bc));

+        ots.addTest(ProvidedServiceTestSuite.suite(bc));

+        ots.addTest(LifeCycleControllerTestSuite.suite(bc));

+        ots.addTest(LifeCycleCallbackTest.suite(bc));

+        ots.addTest(DependencyTestSuite.suite(bc));

+        ots.addTest(ArchitectureTestSuite.suite(bc));

+        ots.addTest(ConfigurationTestSuite.suite(bc));

+        ots.addTest(ExternalHandlerTestSuite.suite(bc));

+        ots.addTest(BadTestSuite.suite(bc));

+        return ots;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandler.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandler.java
new file mode 100644
index 0000000..865234c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandler.java
@@ -0,0 +1,100 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.handler;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.architecture.PropertyDescription;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.osgi.framework.ServiceRegistration;

+

+public class CheckServiceHandler extends PrimitiveHandler implements CheckService {

+	

+	ServiceRegistration sr;

+	boolean isValid;

+	int changes = 0;

+	static final String NAMESPACE = org.apache.felix.ipojo.test.handler.CheckServiceHandler.class.getName();

+	

+	Properties props = new Properties();

+

+	public void configure(Element metadata, Dictionary configuration) {

+		Element[] meta = metadata.getElements("Check", NAMESPACE);

+		if(meta.length == 0) { return;	}		

+		// Get handler props 

+		props.put("instance.name", configuration.get("name"));

+		if(configuration.get("csh.simple") != null) { props.put("Simple", configuration.get("csh.simple")); }

+		if(configuration.get("csh.map") != null) { 

+			Dictionary m = (Dictionary) configuration.get("csh.map");

+			props.put("Map1", m.get("a"));

+			props.put("Map2", m.get("b"));

+			props.put("Map3", m.get("c"));

+		}

+		props.put("changes", new Integer(changes));

+		

+	}

+	

+	public void initializeComponentFactory(ComponentTypeDescription cd, Element metadata) {

+	    cd.addProperty(new PropertyDescription("csh.simple", "java.lang.String", null));

+        cd.addProperty(new PropertyDescription("csh.map", "java.util.Dictionary", null));

+	}

+	

+	public void start() {

+		if(sr == null) {

+			sr = getInstanceManager().getContext().registerService(CheckService.class.getName(), this, props);

+		}

+		isValid = true;

+	}

+	

+	public void stop() {

+		isValid = false;

+		synchronized(this) {

+			if(sr != null) { sr.unregister(); }

+		}

+	}

+	

+	public boolean check() {

+		if(isValid) { isValid = false;}

+		else { isValid = true; }

+		return isValid;

+	}

+

+	public Properties getProps() {

+		return props;

+	}

+	

+	public void stateChanged(int state) {

+		changes++;

+		props.put("changes", new Integer(changes));

+		sr.setProperties(props);

+	}

+

+	public String getName() {

+		return NAMESPACE;

+	}

+	

+	public HandlerDescription getDescription() {

+		return new CheckServiceHandlerDescription(this);

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandlerDescription.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandlerDescription.java
new file mode 100644
index 0000000..fb43042
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/handler/CheckServiceHandlerDescription.java
@@ -0,0 +1,38 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.handler;

+

+import org.apache.felix.ipojo.Handler;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+

+public class CheckServiceHandlerDescription extends HandlerDescription {

+

+	public CheckServiceHandlerDescription(Handler h) {

+		super(h);

+	}

+	

+	public Element getHandlerInfo() {

+		Element elem = super.getHandlerInfo();

+		elem.addAttribute(new Attribute("isValid", isValid()+""));

+		return elem;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/DefaultLogImpl.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/DefaultLogImpl.java
new file mode 100644
index 0000000..bbde9eb
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/DefaultLogImpl.java
@@ -0,0 +1,65 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.log;

+

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.log.LogService;

+

+public class DefaultLogImpl implements LogService {

+    

+

+    public void log(int arg0, String arg1) {

+        dispatch(arg0, arg1);

+    }

+

+    public void log(int arg0, String arg1, Throwable arg2) {

+        dispatch(arg0, arg1 + " (" + arg2.getMessage() + ")");

+    }

+

+    public void log(ServiceReference arg0, int arg1, String arg2) {

+        dispatch(arg1, arg2 + " (" + arg0.toString() + ")");

+    }

+

+    public void log(ServiceReference arg0, int arg1, String arg2, Throwable arg3) {

+        dispatch(arg1, arg2 + " (" + arg0.toString() + ")" + " (" + arg3.getMessage() + ")");

+    }

+    

+    

+    private void dispatch(int level, String message) {

+        switch (level) {

+            case LogService.LOG_DEBUG:

+                System.out.println("[DEBUG] " + message);

+                break;

+            case LogService.LOG_INFO:

+                System.out.println("[INFO] " + message);

+                break;

+            case LogService.LOG_WARNING:

+                System.out.println("[WARNING] " + message);

+                break; 

+            case LogService.LOG_ERROR:

+                System.out.println("[ERROR] " + message);

+                break;

+            default:

+                System.out.println("[" + level + "] " + message);

+                break;

+        }

+    }

+

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/LogImpl.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/LogImpl.java
new file mode 100644
index 0000000..9f23faf
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/log/LogImpl.java
@@ -0,0 +1,131 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.log;

+

+import java.util.Enumeration;

+import java.util.Vector;

+

+import org.osgi.framework.Bundle;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.log.LogEntry;

+import org.osgi.service.log.LogListener;

+import org.osgi.service.log.LogReaderService;

+import org.osgi.service.log.LogService;

+

+public class LogImpl implements LogService, LogReaderService {

+    

+    Vector m_messages = new Vector();

+

+    public void log(int arg0, String arg1) {

+       add(new LogEntryImpl(arg0, arg1, null, null));

+    }

+

+    public void log(final int arg0, final String arg1, final Throwable arg2) {

+        Runnable runnable = new Runnable() {

+            public void run() {

+                add(new LogEntryImpl(arg0, arg1, arg2, null));

+            }

+        };

+        Thread thread = new Thread(runnable);

+        thread.start();

+    }

+

+    public void log(final ServiceReference arg0, final int arg1, final String arg2) {

+        Runnable runnable = new Runnable() {

+            public void run() {

+                add(new LogEntryImpl(arg1, arg2, null, arg0));

+            }

+        };

+        Thread thread = new Thread(runnable);

+        thread.start();

+    }

+

+    public void log(final ServiceReference arg0, final int arg1, final String arg2, final Throwable arg3) {

+//        Runnable runnable = new Runnable() {

+//            public void run() {

+//                add(new LogEntryImpl(arg1, arg2, arg3, arg0));

+//            }

+//        };

+//        Thread thread = new Thread(runnable);

+//        thread.start();

+    }

+    

+    private void add(LogEntry entry) {

+        m_messages.add(entry);

+    }

+

+    public void addLogListener(LogListener arg0) {

+        throw new UnsupportedOperationException("Log Listener not supported");

+        

+    }

+

+    public Enumeration getLog() {

+       return m_messages.elements();

+    }

+

+    public void removeLogListener(LogListener arg0) {

+        throw new UnsupportedOperationException("Log Listener not supported");

+        

+    }

+    

+    private class LogEntryImpl implements LogEntry {

+        

+        private int level;

+        private String message;

+        private Throwable exception;

+        private ServiceReference reference;

+        private long time;

+        

+

+        LogEntryImpl(int l, String m, Throwable e, ServiceReference ref) {

+            level = l;

+            message = m;

+            exception = e;

+            reference = ref;

+            time = System.currentTimeMillis();

+        }

+        

+        

+        public Bundle getBundle() {

+           return null;

+        }

+

+        public Throwable getException() {

+            return exception;

+        }

+

+        public int getLevel() {

+            return level;

+        }

+

+        public String getMessage() {

+            return message;

+        }

+

+        public ServiceReference getServiceReference() {

+            return reference;

+        }

+

+        public long getTime() {

+            return time;

+        }

+        

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ArchitectureTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ArchitectureTestSuite.java
new file mode 100644
index 0000000..ef287b6
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ArchitectureTestSuite.java
@@ -0,0 +1,35 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.architecture;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ArchitectureTestSuite {

+

+    public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Architecture Test Suite", bc);

+		ots.addTestSuite(ProvidedServiceTest.class);

+		ots.addTestSuite(DependencyTest.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/DependencyTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/DependencyTest.java
new file mode 100644
index 0000000..102df0b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/DependencyTest.java
@@ -0,0 +1,600 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.architecture;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.handlers.dependency.DependencyHandlerDescription;

+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandlerDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DependencyTest extends OSGiTestCase {

+	

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	ComponentInstance instance1, instance2, instance3, instance4;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Optional");

+			instance2 = Utils.getFactoryByName(context, "SimpleOptionalCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Multiple");

+			instance3 = Utils.getFactoryByName(context, "SimpleMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "OptionalMultiple");

+			instance4 = Utils.getFactoryByName(context, "SimpleOptionalMultipleCheckServiceProvider").createComponentInstance(i4);

+		} catch(Exception e) {

+			throw new RuntimeException(e.getMessage());

+		}

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	private DependencyHandlerDescription getDependencyDesc(InstanceDescription id) {

+		for(int i = 0; i < id.getHandlers().length; i++) {

+			if(id.getHandlers()[i].getHandlerName().equals("org.apache.felix.ipojo.handlers.dependency.DependencyHandler")) {

+				return (DependencyHandlerDescription) id.getHandlers()[i];

+			}

+		}

+		fail("Dependency Handler not found");

+		return null;

+	}

+	

+	private ProvidedServiceHandlerDescription getPSDesc(InstanceDescription id) {

+		for(int i = 0; i < id.getHandlers().length; i++) {

+			if(id.getHandlers()[i].getHandlerName().equals("org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler")) {

+				return (ProvidedServiceHandlerDescription) id.getHandlers()[i];

+			}

+		}

+		fail("Provided Service Handler not found");

+		return null;

+	}

+	

+	public void testSimpleDependency() {

+		ServiceReference arch_dep = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_dep);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+		

+		// Check dependency handler invalidity

+		DependencyHandlerDescription dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		// Check dependency metadata

+		assertEquals("Check dependency interface", dhd.getDependencies()[0].getInterface(), FooService.class.getName());

+		assertFalse("Check dependency cardinality", dhd.getDependencies()[0].isMultiple());

+		assertFalse("Check dependency optionality", dhd.getDependencies()[0].isOptional());

+		assertNull("Check dependency ref -1", dhd.getDependencies()[0].getServiceReferences());

+		

+		fooProvider1.start();

+		

+		ServiceReference arch_ps = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps);

+		InstanceDescription id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh = getPSDesc(id_ps);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+		dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		fooProvider1.start();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		arch_ps = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps.getState() == ComponentInstance.VALID);

+		psh = getPSDesc(id_ps);

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		

+		assertEquals("Check dependency ref -3", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph 

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		psh = getPSDesc(id_ps);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+		dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		id_dep = null;

+		cs = null;

+		context.ungetService(arch_dep);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testOptionalDependency() {

+		ServiceReference arch_dep = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_dep);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check dependency handler invalidity

+		DependencyHandlerDescription dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		// Check dependency metadata

+		assertEquals("Check dependency interface", dhd.getDependencies()[0].getInterface(), FooService.class.getName());

+		assertFalse("Check dependency cardinality", dhd.getDependencies()[0].isMultiple());

+		assertTrue("Check dependency optionality", dhd.getDependencies()[0].isOptional());

+		assertNull("Check dependency ref -1", dhd.getDependencies()[0].getServiceReferences());

+		

+		fooProvider1.start();

+		

+		ServiceReference arch_ps = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps);

+		InstanceDescription id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh = getPSDesc(id_ps);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		fooProvider1.start();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		arch_ps = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps.getState() == ComponentInstance.VALID);

+		psh = getPSDesc(id_ps);

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		

+		assertEquals("Check dependency ref -3", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph 

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps = ((Architecture) context.getService(arch_ps)).getInstanceDescription();

+		psh = getPSDesc(id_ps);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		id_dep = null;

+		cs = null;

+		context.ungetService(arch_dep);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testMultipleDependency() {

+		ServiceReference arch_dep = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_dep);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+		

+		// Check dependency handler invalidity

+		DependencyHandlerDescription dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		// Check dependency metadata

+		assertEquals("Check dependency interface", dhd.getDependencies()[0].getInterface(), FooService.class.getName());

+		assertTrue("Check dependency cardinality", dhd.getDependencies()[0].isMultiple());

+		assertFalse("Check dependency optionality", dhd.getDependencies()[0].isOptional());

+		assertNull("Check dependency ref -1", dhd.getDependencies()[0].getServiceReferences());

+		

+		fooProvider1.start();

+		

+		ServiceReference arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		InstanceDescription id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id_ps1.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		assertEquals("Check used ref - 1 (" + dhd.getDependencies()[0].getUsedServices().size() + ")", dhd.getDependencies()[0].getUsedServices().size(), 0);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 2", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		// Start a second foo service provider

+		fooProvider2.start();

+		

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		ServiceReference arch_ps2 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		assertNotNull("Check architecture 2 availability", arch_ps2);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		InstanceDescription id_ps2 = ((Architecture) context.getService(arch_ps2)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);

+		assertTrue("Check instance 2 invalidity - 1", id_ps2.getState() == ComponentInstance.VALID);

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 3 ", dhd.getDependencies()[0].getServiceReferences().size(), 2);

+		assertEquals("Check used ref - 2 ", dhd.getDependencies()[0].getUsedServices().size(), 1); // provider 2 not already used

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		id_ps2 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh1 = getPSDesc(id_ps1);

+		ProvidedServiceHandlerDescription psh2 = getPSDesc(id_ps2);

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertEquals("Check POJO creation", id_ps2.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 3.1", dhd.getDependencies()[0].getUsedServices().contains(psh1.getProvidedServices()[0].getServiceReference()));

+		assertTrue("Check service reference - 3.2", dhd.getDependencies()[0].getUsedServices().contains(psh2.getProvidedServices()[0].getServiceReference()));

+		assertEquals("Check used ref - 3 ("+dhd.getDependencies()[0].getUsedServices().size()+")", dhd.getDependencies()[0].getUsedServices().size(), 2);

+		

+		fooProvider2.stop();

+		

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id_ps1.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		assertEquals("Check used ref - 4 ", dhd.getDependencies()[0].getUsedServices().size(), 1);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		assertEquals("Check used ref - 5 ", dhd.getDependencies()[0].getUsedServices().size(), 1);

+		

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertFalse("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		fooProvider2.start();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);

+		psh = getPSDesc(id_ps1);

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		

+		assertEquals("Check dependency ref -3", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		assertEquals("Check used ref - 6 ", dhd.getDependencies()[0].getUsedServices().size(), 0);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph 

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertTrue("Check service reference - 4", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		assertEquals("Check used ref - 7 ", dhd.getDependencies()[0].getUsedServices().size(), 1);

+		

+		fooProvider2.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertFalse("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertFalse("Check dependency handler invalidity", dhd.isValid());

+		

+		id_dep = null;

+		cs = null;

+		context.ungetService(arch_dep);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testMultipleOptionalDependency() {

+		ServiceReference arch_dep = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_dep);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check dependency handler invalidity

+		DependencyHandlerDescription dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		// Check dependency metadata

+		assertEquals("Check dependency interface", dhd.getDependencies()[0].getInterface(), FooService.class.getName());

+		assertTrue("Check dependency cardinality", dhd.getDependencies()[0].isMultiple());

+		assertTrue("Check dependency optionality", dhd.getDependencies()[0].isOptional());

+		assertNull("Check dependency ref -1", dhd.getDependencies()[0].getServiceReferences());

+		

+		fooProvider1.start();

+		

+		ServiceReference arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		InstanceDescription id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 1", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+		

+		// Start a second foo service provider

+		fooProvider2.start();

+		

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		ServiceReference arch_ps2 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		assertNotNull("Check architecture 2 availability", arch_ps2);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		InstanceDescription id_ps2 = ((Architecture) context.getService(arch_ps2)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);

+		assertTrue("Check instance 2 invalidity - 1", id_ps2.getState() == ComponentInstance.VALID);

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 3 ", dhd.getDependencies()[0].getServiceReferences().size(), 2);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		id_ps2 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		ProvidedServiceHandlerDescription psh1 = getPSDesc(id_ps1);

+		ProvidedServiceHandlerDescription psh2 = getPSDesc(id_ps2);

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertEquals("Check POJO creation", id_ps2.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 2.1", dhd.getDependencies()[0].getUsedServices().contains(psh1.getProvidedServices()[0].getServiceReference()));

+		assertTrue("Check service reference - 2.2", dhd.getDependencies()[0].getUsedServices().contains(psh2.getProvidedServices()[0].getServiceReference()));

+		

+		fooProvider2.stop();

+		

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);				

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		assertEquals("Check dependency ref - 2 ", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertEquals("Check POJO creation", id_ps1.getCreatedObjects().length, 1);

+		assertTrue("Check service reference - 3", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+

+		fooProvider1.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		fooProvider2.start();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		arch_ps1 = Utils.getServiceReferenceByName(context, Architecture.class.getName(), fooProvider2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ps1);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_ps1.getState() == ComponentInstance.VALID);

+		psh = getPSDesc(id_ps1);

+		assertTrue("Check instance validity", id_dep.getState() == ComponentInstance.VALID);

+		assertTrue("Check dependency handler validity", dhd.isValid());

+		

+		assertEquals("Check dependency ref -3", dhd.getDependencies()[0].getServiceReferences().size(), 1);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check object graph 

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		dhd = getDependencyDesc(id_dep);

+		id_ps1 = ((Architecture) context.getService(arch_ps1)).getInstanceDescription();

+		psh = getPSDesc(id_ps1);

+		assertEquals("Check Service Reference equality", psh.getProvidedServices()[0].getServiceReference(), dhd.getDependencies()[0].getServiceReference());

+		assertTrue("Check service reference - 4", dhd.getDependencies()[0].getUsedServices().contains(psh.getProvidedServices()[0].getServiceReference()));

+

+		fooProvider2.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_dep)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.VALID);

+		dhd = getDependencyDesc(id_dep);

+		assertTrue("Check dependency handler invalidity", dhd.isValid());

+		

+		id_dep = null;

+		cs = null;

+		context.ungetService(arch_dep);

+		context.ungetService(cs_ref);

+	}

+	

+	

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ProvidedServiceTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ProvidedServiceTest.java
new file mode 100644
index 0000000..efcd2da
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/architecture/ProvidedServiceTest.java
@@ -0,0 +1,199 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.architecture;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.HandlerDescription;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;

+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandlerDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ProvidedServiceTest extends OSGiTestCase {

+	

+	

+	public void testExposition() {

+		String factName = "FooProviderType-1";

+		String compName = "FooProvider-1";

+		

+		// Get the factory to create a component instance

+		Factory fact = Utils.getFactoryByName(context, factName);

+		assertNotNull("Cannot find the factory FooProvider-1", fact);

+		

+		Properties props = new Properties();

+		props.put("name", compName);

+		ComponentInstance ci = null;

+		try {

+			ci = fact.createComponentInstance(props);

+		} catch (Exception e) {

+			fail(e.getMessage());

+		}

+

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "FooProvider-1");

+		assertNotNull("Architecture not available", arch_ref);

+

+		Architecture arch = (Architecture) context.getService(arch_ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertEquals("Check component instance name (" + id.getName() + ")", id.getName(), compName);

+		assertEquals("Check component type implementation class", id.getComponentDescription().getClassName(), "org.apache.felix.ipojo.test.scenarios.component.FooProviderType1");

+		

+		HandlerDescription[] handlers = id.getHandlers();

+		assertEquals("Number of handlers", handlers.length, 2);

+		

+		//Look for the ProvidedService Handler

+		ProvidedServiceHandlerDescription pshd = null;

+		for(int i = 0; i < handlers.length; i++) {

+			if(handlers[i].getHandlerName().equals("org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler")) {

+				pshd = (ProvidedServiceHandlerDescription) handlers[i];

+			}

+		}

+		

+		assertNotNull("Check ProvidedServiceHandlerDescription", pshd);

+		ProvidedServiceDescription[] ps = pshd.getProvidedServices();

+		

+		assertEquals("Check ProvidedService number", ps.length, 1);

+		assertEquals("Check Provided Service Specs - 1", ps[0].getServiceSpecification().length, 1);

+		assertEquals("Check Provided Service Specs - 2", ps[0].getServiceSpecification()[0], FooService.class.getName());

+		assertEquals("Check Provided Service availability", ps[0].getState(), ProvidedServiceDescription.REGISTERED);

+		Properties prop = ps[0].getProperties();

+		assertNotNull("Check Props", prop);

+		assertEquals("Check service properties number", prop.size(), 2);

+		assertEquals("Check instance.name property", prop.getProperty("instance.name"), compName);

+		assertEquals("Check factory.name property", prop.getProperty("factory.name"), factName);

+		

+		ci.dispose();

+	}

+	

+	public void testProps() {

+		String factName = "FooProviderType-3";

+		String compName = "FooProvider";

+		

+		// Get the factory to create a component instance

+		Factory fact = Utils.getFactoryByName(context, factName);

+		assertNotNull("Cannot find the factory FooProvider", fact);

+		

+		Properties props = new Properties();

+		props.put("name", compName);

+		props.put("foo", "foo");

+		props.put("bar", "2");

+		props.put("baz", "baz");

+		ComponentInstance ci = null;

+		try {

+			ci = fact.createComponentInstance(props);

+		} catch (Exception e) { fail(e.getMessage()); }

+

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), compName);

+		assertNotNull("Architecture not available", arch_ref);

+

+		Architecture arch = (Architecture) context.getService(arch_ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertEquals("Check component instance name (" + id.getName() + ")", id.getName(), compName);

+		assertEquals("Check component type implementation class", id.getComponentDescription().getClassName(), "org.apache.felix.ipojo.test.scenarios.component.FooProviderType1");

+		

+		HandlerDescription[] handlers = id.getHandlers();

+		assertEquals("Number of handlers", handlers.length, 3);

+		

+		//Look for the ProvidedService Handler

+		ProvidedServiceHandlerDescription pshd = null;

+		for(int i = 0; i < handlers.length; i++) {

+			if(handlers[i].getHandlerName().equals("org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler")) {

+				pshd = (ProvidedServiceHandlerDescription) handlers[i];

+			}

+		}

+		

+		assertNotNull("Check ProvidedServiceHandlerDescription", pshd);

+		ProvidedServiceDescription[] ps = pshd.getProvidedServices();

+		

+		assertEquals("Check ProvidedService number", ps.length, 1);

+		assertEquals("Check Provided Service Specs - 1", ps[0].getServiceSpecification().length, 1);

+		assertEquals("Check Provided Service Specs - 2", ps[0].getServiceSpecification()[0], FooService.class.getName());

+		assertEquals("Check Provided Service availability", ps[0].getState(), ProvidedServiceDescription.REGISTERED);

+	

+		Properties prop = ps[0].getProperties();

+		assertNotNull("Check Props", prop);

+		assertEquals("Check service properties number (#" + prop + "?=5)" , prop.size(), 5);

+		assertEquals("Check instance.name property", prop.getProperty("instance.name"), compName);

+		assertEquals("Check factory.name property", prop.getProperty("factory.name"), factName);

+		assertEquals("Check foo property", prop.getProperty("foo"), "foo");

+		assertEquals("Check bar property", prop.getProperty("bar"), "2");

+		assertEquals("Check baz property", prop.getProperty("baz"), "baz");

+		

+		ci.dispose();

+	}

+	

+	public void testDoubleProviding() {

+		String factName = "FooBarProviderType-1";

+		String compName = "FooProvider";

+		

+		// Get the factory to create a component instance

+		Factory fact = Utils.getFactoryByName(context, factName);

+		assertNotNull("Cannot find the factory FooProvider", fact);

+		

+		Properties props = new Properties();

+		props.put("name", compName);

+		ComponentInstance ci = null;

+		try {

+			ci = fact.createComponentInstance(props);

+		} catch (Exception e) {

+			fail(e.getMessage());

+		}

+

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), compName);

+		assertNotNull("Architecture not available", arch_ref);

+

+		Architecture arch = (Architecture) context.getService(arch_ref);

+		InstanceDescription id = arch.getInstanceDescription();

+		

+		assertEquals("Check component instance name (" + id.getName() + ")", id.getName(), compName);

+		assertEquals("Check component type implementation class", id.getComponentDescription().getClassName(), "org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1");

+		

+		HandlerDescription[] handlers = id.getHandlers();

+		assertEquals("Number of handlers", handlers.length, 2);

+		

+		//Look for the ProvidedService Handler

+		ProvidedServiceHandlerDescription pshd = null;

+		for(int i = 0; i < handlers.length; i++) {

+			if(handlers[i].getHandlerName().equals("org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler")) {

+				pshd = (ProvidedServiceHandlerDescription) handlers[i];

+			}

+		}

+		

+		assertNotNull("Check ProvidedServiceHandlerDescription", pshd);

+		ProvidedServiceDescription[] ps = pshd.getProvidedServices();

+		

+		assertEquals("Check ProvidedService number", ps.length, 1);

+		assertEquals("Check Provided Service Specs - 1", ps[0].getServiceSpecification().length, 2);

+		assertContains("Check provided service specs - 2", ps[0].getServiceSpecification(), FooService.class.getName());;

+		assertContains("Check provided service specs - 2", ps[0].getServiceSpecification(), BarService.class.getName());

+		assertEquals("Check Provided Service availability", ps[0].getState(), ProvidedServiceDescription.REGISTERED);

+		

+		ci.dispose();

+	}

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadFactories.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadFactories.java
new file mode 100644
index 0000000..baa6fee
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadFactories.java
@@ -0,0 +1,77 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.bad;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.HandlerFactory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+

+public class BadFactories extends OSGiTestCase {

+    

+    private Element getElementFactoryWithNoClassName() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("name", "noclassname"));

+        return elem;        

+    }

+    

+    private Element getElementHandlerFactoryWithNoClassName() {

+        Element elem = new Element("handler", "");

+        elem.addAttribute(new Attribute("name", "noclassname"));

+        return elem;        

+    }

+    

+    private Element getElementHandlerFactoryWithNoName() {

+        Element elem = new Element("handler", "");

+        elem.addAttribute(new Attribute("className", "noclassname"));

+        return elem;        

+    }

+    

+    public void testBadFactory() {

+        try {

+            new ComponentFactory(context, getElementFactoryWithNoClassName());

+            fail("A factory with no class name must be rejected");

+        } catch (ConfigurationException e) {

+          // OK.   

+        }

+    }

+    

+    public void testBadHandlerFactory1() {

+        try {

+            new HandlerFactory(context, getElementHandlerFactoryWithNoClassName());

+            fail("An handler factory with no class name must be rejected");

+        } catch (ConfigurationException e) {

+          // OK.   

+        }

+    }

+    

+    public void testBadHandlerFactory2() {

+        try {

+            new HandlerFactory(context, getElementHandlerFactoryWithNoName());

+            fail("An handler factory with no name must be rejected");

+        } catch (ConfigurationException e) {

+          // OK.   

+        }

+    }

+    

+    

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCCallback.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCCallback.java
new file mode 100644
index 0000000..8be6ac4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCCallback.java
@@ -0,0 +1,254 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.bad;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.MissingHandlerException;

+import org.apache.felix.ipojo.UnacceptableConfiguration;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

+import org.apache.felix.ipojo.parser.ParseException;

+

+public class BadLFCCallback extends OSGiTestCase {

+    

+    private String clazz = "org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService";

+    private String type = "CallbackCheckService";

+    private Element manipulation;

+    private Properties props;

+    

+    public void setUp() {

+        manipulation = getManipulationForComponent();

+        props = new Properties();

+        props.put("name", "BAD");

+    }

+    

+    

+    private Element getNothing() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getNoTransition() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        callback.addAttribute(new Attribute("method", "start"));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getNoMethod() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        callback.addAttribute(new Attribute("transition", "validate"));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadMethod() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        callback.addAttribute(new Attribute("transition", "validate"));

+        callback.addAttribute(new Attribute("method", "start_")); // Missing method.

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadMethod2() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        callback.addAttribute(new Attribute("transition", "invalidate"));

+        callback.addAttribute(new Attribute("method", "stop_")); // Missing method.

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadTransition() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("callback", "");

+        callback.addAttribute(new Attribute("method", "start"));

+        callback.addAttribute(new Attribute("transition", "validate_"));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getManipulationForComponent() {

+        String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+        Element elem = null;

+        try {

+            elem = ManifestMetadataParser.parse(header);

+        } catch (ParseException e) {

+            fail("Parse Exception when parsing iPOJO-Component");

+        }

+        

+        assertNotNull("Check elem not null", elem);

+        

+        Element manip = getManipulationForComponent(elem, type);

+        assertNotNull("Check manipulation metadata not null for " + type, manip);

+        return manip;

+    }

+    

+    private Element getManipulationForComponent(Element metadata, String comp_name) {

+        Element[] comps = metadata.getElements("component");

+        for(int i = 0; i < comps.length; i++) {

+            if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+        }

+        return null;

+    }

+    

+    public void testNothing() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNothing());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A lifecycle callback with a missing method and transition must be rejected " + cf);

+        } catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testNoTransition() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNoTransition());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A lifecycle callback with a missing transition must be rejected " + cf);

+        } catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testNoMethod() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNoMethod());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A lifecycle callback with a missing method must be rejected " + cf);

+        }catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadMethod() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadMethod());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            if (ci.isStarted()) {

+                fail("A lifecycle callback with a bad method must be rejected (instance stills valid)" + cf);

+            }

+            ci.dispose();

+            cf.stop();

+        } catch (ConfigurationException e) {

+            //The check does not happen in the configure method.

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadMethod2() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadMethod2());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.stop();

+            if (ci.isStarted()) {

+                fail("A lifecycle callback with a bad method must be rejected (instance stills valid)" + cf);

+            }

+            ci.dispose();

+            cf.stop();

+        } catch (ConfigurationException e) {

+            //The check does not happen in the configure method.

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadTransition() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadTransition());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A lifecycle callback with a bad transition must be rejected " + cf);

+        } catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCController.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCController.java
new file mode 100644
index 0000000..8816530
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadLFCController.java
@@ -0,0 +1,103 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.bad;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

+import org.apache.felix.ipojo.parser.ParseException;

+

+public class BadLFCController extends OSGiTestCase {

+    

+    private String clazz = "org.apache.felix.ipojo.test.scenarios.component.LifecycleControllerTest";

+    

+    private Element getNoFieldController() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element controller = new Element("controller", "");

+        elem.addElement(controller);

+        return elem;

+    }

+    

+    private Element getBadFieldController() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element controller = new Element("controller", "");

+        controller.addAttribute(new Attribute("field", "controller")); // Missing field

+        elem.addElement(controller);

+        elem.addElement(getManipulationForComponent("lcTest"));

+        return elem;

+    }

+    

+    private Element getManipulationForComponent(String comp_name) {

+        String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+        Element elem = null;

+        try {

+            elem = ManifestMetadataParser.parse(header);

+        } catch (ParseException e) {

+            fail("Parse Exception when parsing iPOJO-Component");

+        }

+        

+        assertNotNull("Check elem not null", elem);

+        

+        Element manip = getManipulationForComponent(elem, comp_name);

+        assertNotNull("Check manipulation metadata not null for " + comp_name, manip);

+        return manip;

+    }

+    

+    private Element getManipulationForComponent(Element metadata, String comp_name) {

+        Element[] comps = metadata.getElements("component");

+        for(int i = 0; i < comps.length; i++) {

+            if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+        }

+        return null;

+    }

+    

+    public void testNoField() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNoFieldController());

+            cf.start();

+            cf.stop();

+            fail("A lifecycle controller with a missing field must be rejected " + cf);

+        } catch (Exception e) {

+            // OK

+        }

+    }

+    

+    public void testBadField() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadFieldController());

+            cf.start();

+            cf.stop();

+            fail("A lifecycle controller with a bad field must be rejected " + cf);

+        } catch (Exception e) {

+            // OK

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadServiceDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadServiceDependencies.java
new file mode 100644
index 0000000..5bd57c0
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadServiceDependencies.java
@@ -0,0 +1,231 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.bad;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.MissingHandlerException;

+import org.apache.felix.ipojo.UnacceptableConfiguration;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Attribute;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

+import org.apache.felix.ipojo.parser.ParseException;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+

+public class BadServiceDependencies extends OSGiTestCase {

+    

+    private String clazz = "org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider";

+    private String type = "BothCheckServiceProvider";

+    private Element manipulation;

+    private Properties props;

+    

+    public void setUp() {

+        manipulation = getManipulationForComponent();

+        props = new Properties();

+        props.put("name", "BAD");

+    }

+    

+    

+    private Element getNothing() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getNoField() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        callback.addAttribute(new Attribute("filter", "(foo=bar)"));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadField() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        callback.addAttribute(new Attribute("field", "BAD_FIELD")); // missing field.

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadFilter() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        callback.addAttribute(new Attribute("field", "fs"));

+        callback.addAttribute(new Attribute("filter", "(foo=bar)&(bar=foo)")); // Incorrect filter

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadType() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        callback.addAttribute(new Attribute("field", "fs"));

+        callback.addAttribute(new Attribute("interface", BarService.class.getName()));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    private Element getBadAggregate() {

+        Element elem = new Element("component", "");

+        elem.addAttribute(new Attribute("classname", clazz));

+        

+        Element callback = new Element("requires", "");

+        callback.addAttribute(new Attribute("field", "fs"));

+        callback.addAttribute(new Attribute("aggregate", "true"));

+        elem.addElement(callback);

+        elem.addElement(manipulation);

+        return elem;

+    }

+    

+    

+    private Element getManipulationForComponent() {

+        String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+        Element elem = null;

+        try {

+            elem = ManifestMetadataParser.parse(header);

+        } catch (ParseException e) {

+            fail("Parse Exception when parsing iPOJO-Component");

+        }

+        

+        assertNotNull("Check elem not null", elem);

+        

+        Element manip = getManipulationForComponent(elem, type);

+        assertNotNull("Check manipulation metadata not null for " + type, manip);

+        return manip;

+    }

+    

+    private Element getManipulationForComponent(Element metadata, String comp_name) {

+        Element[] comps = metadata.getElements("component");

+        for(int i = 0; i < comps.length; i++) {

+            if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+        }

+        return null;

+    }

+    

+    public void testNothing() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNothing());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A service requirement with neither field and method must be rejected " + cf);

+        } catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testNoField() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getNoField());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A service requirement with neither field and method must be rejected " + cf);

+        } catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadField() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadField());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A service requirement with a bad field must be rejected " + cf);

+        }catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadFilter() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadFilter());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A service requirement with a bad filter must be rejected " + cf);

+        }catch (ConfigurationException e) {

+            //OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+    

+    public void testBadType() {

+        try {

+            ComponentFactory cf = new ComponentFactory(context, getBadType());

+            cf.start();

+            ComponentInstance ci = cf.createComponentInstance(props);

+            ci.dispose();

+            cf.stop();

+            fail("A service requirement with a bad type must be rejected " + cf);

+        }catch (ConfigurationException e) {

+           // OK

+        } catch (UnacceptableConfiguration e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        } catch (MissingHandlerException e) {

+            fail("Unexpected exception when creating an instance : " + e.getMessage());

+        }

+    }

+  }

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadTestSuite.java
new file mode 100644
index 0000000..71d7db0
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/bad/BadTestSuite.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.bad;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class BadTestSuite {

+    

+    public static Test suite(BundleContext bc) {

+        OSGiTestSuite ots = new OSGiTestSuite("Bad configuration test suite", bc);

+        ots.addTestSuite(BadFactories.class);

+        ots.addTestSuite(BadLFCController.class);

+        ots.addTestSuite(BadLFCCallback.class);

+        ots.addTestSuite(BadServiceDependencies.class);

+        return ots;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/CheckService2Provider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/CheckService2Provider.java
new file mode 100644
index 0000000..9202b1d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/CheckService2Provider.java
@@ -0,0 +1,30 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.A123;

+

+import org.apache.felix.ipojo.test.scenarios.service.A123.CheckService2;

+

+public class CheckService2Provider implements CheckService2 {

+

+	public boolean check() {

+		// TODO Auto-generated method stub

+		return false;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/Manipulation23Tester.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/Manipulation23Tester.java
new file mode 100644
index 0000000..fe17b96
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/A123/Manipulation23Tester.java
@@ -0,0 +1,124 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.A123;

+

+import org.apache.felix.ipojo.test.scenarios.service.PrimitiveManipulationTestService;

+

+

+public class Manipulation23Tester implements PrimitiveManipulationTestService {

+

+    

+    // Integer types

+	byte b = 1;

+	short s = 1;

+	int i = 1;

+	long l = 1;

+	

+	// Floatting types

+	double d = 1.1;

+	float f = 1.1f;

+	

+	// Character

+	char c = 'a';

+	

+	// Boolean

+	boolean bool = false;

+	

+	// Integer arrays 

+	byte[] bs = new byte[] {0,1,2};

+	short[] ss = new short[] {0,1,2};

+	int[] is = new int[] {0,1,2};

+	long[] ls = new long[] {0,1,2};

+	

+	double[] ds = new double[] {0.0, 1.1, 2.2};

+	float[] fs = new float[] {0.0f, 1.1f, 2.2f};

+	

+	char[] cs = new char[] {'a', 'b', 'c'};

+	

+	boolean[] bools = new boolean[] {false, true, false};

+

+	public boolean getBoolean() { return bool; }

+

+	public boolean[] getBooleans() { return bools; }

+

+	public byte getByte() { return b; }

+

+	public byte[] getBytes() { return bs; }

+

+	public char getChar() { return c; }

+

+	public char[] getChars() { return cs; }

+

+	public double getDouble() { return d; }

+

+	public double[] getDoubles() { return ds; }

+

+	public float getFloat() { return f; }

+

+	public float[] getFloats() { return fs; }

+

+	public int getInt() { return i; }

+

+	public int[] getInts() { return is; }

+

+	public long getLong() { return l; }

+

+	public long[] getLongs() { return ls; }

+

+	public short getShort() { return s; }

+

+	public short[] getShorts() { return ss; }

+

+	public void setBoolean(boolean b) { this.bool = b; }

+

+	public void setBooleans(boolean[] bs) { this.bools = bs; }

+

+	public void setByte(byte b) { this.b = b; }

+

+	public void setBytes(byte[] bs) { this.bs = bs; }

+

+	public void setChar(char c) { this.c = c; }

+

+	public void setChars(char[] cs) { this.cs = cs; }

+

+	public void setDouble(double d) { this.d = d; }

+

+	public void setDoubles(double[] ds) { this.ds = ds; }

+

+	public void setFloat(float f) { this.f = f; }

+

+	public void setFloats(float[] fs) { this.fs = fs; }

+

+	public void setInt(int i) { this.i = i; }

+

+	public void setInts(int[] is) { this.is = is; }

+

+	public void setLong(long l) { this.l = l; }

+

+	public void setLongs(long[] ls) { this.ls = ls; }

+

+ 	public void setShort(short s) { this.s = s; }

+

+	public void setShorts(short[] ss) { this.ss = ss; }	

+	

+	public void setLong(long l, String s) {

+	    this.l = l;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Baz2CheckProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Baz2CheckProvider.java
new file mode 100644
index 0000000..1e7cb1d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Baz2CheckProvider.java
@@ -0,0 +1,81 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class Baz2CheckProvider implements CheckService {

+	

+	BazService fs;

+	

+	int simpleB = 0;

+	int objectB = 0;

+	int refB = 0;

+	int simpleU = 0;

+	int objectU = 0;

+	int refU = 0;

+

+	public boolean check() {

+		return fs.foo();

+	}

+

+	public Properties getProps() {

+		Properties props = new Properties();

+		props.put("result", new Boolean(fs.foo()));

+		props.put("voidB", new Integer(simpleB));

+		props.put("objectB", new Integer(objectB));

+		props.put("refB", new Integer(refB));

+		props.put("voidU", new Integer(simpleU));

+		props.put("objectU", new Integer(objectU));

+		props.put("refU", new Integer(refU));

+		props.put("boolean", new Boolean(fs.getBoolean()));

+		props.put("int", new Integer(fs.getInt()));

+		props.put("long", new Long(fs.getLong()));

+		props.put("double", new Double(fs.getDouble()));

+		if(fs.getObject() != null) { props.put("object", fs.getObject()); }

+		

+		return props;

+	}

+	

+	private void voidBind() {

+		simpleB++;

+	}

+	private void voidUnbind() {

+		simpleU++;

+	}

+	

+	protected void objectBind(Object o) {

+		if(o != null && o instanceof FooService) { objectB++; }

+	}

+	protected void objectUnbind(Object o) {

+		if(o != null && o instanceof FooService) { objectU++; }

+	}

+	

+	public void refBind(ServiceReference sr) {

+		if(sr != null) { refB++; }

+	}

+	public void refUnbind(ServiceReference sr) {

+		if(sr != null) { refU++; }

+	}

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/BazProviderType1.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/BazProviderType1.java
new file mode 100644
index 0000000..4d9a9bb
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/BazProviderType1.java
@@ -0,0 +1,51 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.BazService;

+

+public class BazProviderType1 implements BazService {

+	

+	private int m_bar;

+	private String m_foo;

+

+	public boolean foo() {

+		return true;

+	}

+

+	public Properties fooProps() {

+		Properties p = new Properties();

+		p.put("bar", new Integer(m_bar));

+		p.put("foo", m_foo);

+		return p;

+	}

+	

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CallbackCheckService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CallbackCheckService.java
new file mode 100644
index 0000000..76176c8
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CallbackCheckService.java
@@ -0,0 +1,68 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class CallbackCheckService extends ParentClass implements CheckService {

+

+    int i = 0;

+

+    FooService fs;

+

+    public static CallbackCheckService singleton;

+

+    public static int count = 0;

+

+    private static CallbackCheckService singleton() {

+        if (singleton == null) {

+            count++;

+            singleton = new CallbackCheckService();

+        }

+        return singleton;

+    }

+

+    public static CallbackCheckService several() {

+        count++;

+        return new CallbackCheckService();

+    }

+

+    private void start() {

+        i++;

+    }

+

+    protected void stop() {

+        i++;

+    }

+

+    public boolean check() {

+        return fs.foo();

+    }

+

+    public Properties getProps() {

+        Properties p = new Properties();

+        p.put("int", new Integer(i));

+        p.put("count", new Integer(count));

+        return p;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckProviderParentClass.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckProviderParentClass.java
new file mode 100644
index 0000000..675fe41
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckProviderParentClass.java
@@ -0,0 +1,51 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public abstract class CheckProviderParentClass {

+    

+    int simpleU = 0;

+    int objectU = 0;

+    int refU = 0;

+    int bothU = 0;

+    

+    

+    public void bothUnbind(FooService o, ServiceReference sr) {

+        if(sr != null && o != null && o instanceof FooService) { bothU++; }

+    }

+    

+    public void refUnbind(ServiceReference sr) {

+        if(sr != null) { refU++; }

+    }

+    

+    public void objectUnbind(FooService o) {

+        if(o != null && o instanceof FooService) { objectU++; }

+        else {

+            System.err.println("Unbind null : " + o);

+        }

+    }

+    

+    public void voidUnbind() {

+        simpleU++;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckServiceProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckServiceProvider.java
new file mode 100644
index 0000000..ffaab9f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/CheckServiceProvider.java
@@ -0,0 +1,81 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class CheckServiceProvider extends CheckProviderParentClass implements CheckService {

+    

+	FooService fs;

+	

+	int simpleB = 0;

+	int objectB = 0;

+	int refB = 0;

+	int bothB = 0;

+

+	public boolean check() {

+		return fs.foo();

+	}

+

+	public Properties getProps() {

+		Properties props = new Properties();

+		props.put("result", new Boolean(fs.foo()));

+		props.put("voidB", new Integer(simpleB));

+		props.put("objectB", new Integer(objectB));

+		props.put("refB", new Integer(refB));

+		props.put("bothB", new Integer(bothB));

+		props.put("voidU", new Integer(simpleU));

+		props.put("objectU", new Integer(objectU));

+		props.put("refU", new Integer(refU));

+		props.put("bothU", new Integer(bothU));

+		props.put("boolean", new Boolean(fs.getBoolean()));

+		props.put("int", new Integer(fs.getInt()));

+		props.put("long", new Long(fs.getLong()));

+		props.put("double", new Double(fs.getDouble()));

+        props.put("static", CheckService.foo);

+        props.put("class", CheckService.class.getName());

+		if(fs.getObject() != null) { props.put("object", fs.getObject()); }

+		return props;

+	}

+	

+	private void voidBind() {

+		simpleB++;

+	}

+	

+	protected void objectBind(FooService o) {

+	    if (o == null) {

+	        System.err.println("Bind receive null !!! ");

+	        return;

+	    }

+		if(o != null && o instanceof FooService) { objectB++; }

+	}

+	

+	public void refBind(ServiceReference sr) {

+		if(sr != null) { refB++; }

+	}

+	

+    public void bothBind(FooService o, ServiceReference sr) {

+	    if(sr != null && o != null && o instanceof FooService) { bothB++; }

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableCheckServiceProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableCheckServiceProvider.java
new file mode 100644
index 0000000..5ae13cb
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableCheckServiceProvider.java
@@ -0,0 +1,202 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+

+public class ConfigurableCheckServiceProvider implements CheckService {

+    

+    // Integer types

+    byte b;

+    short s;

+    int i;

+    long l;

+    

+    // Floatting types

+    double d;

+    float f;

+    

+    // Character

+    char c;

+    

+    // Boolean

+    boolean bool;

+    

+    // Integer arrays 

+    byte[] bs;

+    short[] ss;

+    int[] is;

+    long[] ls;

+    

+    double[] ds;

+    float[] fs;

+    

+    char[] cs;

+    

+    boolean[] bools;

+    

+    String string;

+    String[] strings;

+    

+    int upB, upS, upI, upL, upD, upF, upC, upBool, upBs, upSs, upIs, upLs, upDs, upFs, upCs, upBools, upString, upStrings;

+    

+

+    public boolean check() {

+        return true;

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("b", new Byte(b));

+        props.put("s", new Short(s));

+        props.put("i", new Integer(i));

+        props.put("l", new Long(l));

+        props.put("d", new Double(d));

+        props.put("f", new Float(f));

+        props.put("c", new Character(c));

+        props.put("bool", new Boolean(bool));

+        

+        props.put("bs", bs);

+        props.put("ss", ss);

+        props.put("is", is);

+        props.put("ls", ls);

+        props.put("ds", ds);

+        props.put("fs", fs);

+        props.put("cs", cs);

+        props.put("bools", bools);

+        

+        props.put("upb", new Integer(upB));

+        props.put("ups", new Integer(upS));

+        props.put("upi", new Integer(upI));

+        props.put("upl", new Integer(upL));

+        props.put("upd", new Integer(upD));

+        props.put("upf", new Integer(upF));

+        props.put("upc", new Integer(upC));

+        props.put("upbool", new Integer(upBool));

+        

+        props.put("upbs", new Integer(upBs));

+        props.put("upss", new Integer(upSs));

+        props.put("upis", new Integer(upIs));

+        props.put("upls", new Integer(upLs));

+        props.put("upds", new Integer(upDs));

+        props.put("upfs", new Integer(upFs));

+        props.put("upcs", new Integer(upCs));

+        props.put("upbools", new Integer(upBools));

+        

+        props.put("string", string);

+        props.put("strings", strings);

+        props.put("upstring", new Integer(upString));

+        props.put("upstrings", new Integer(upStrings));

+        

+        return props;

+    }

+    

+    public void updateB(byte bb) {

+        b = bb;

+        upB++;

+    }

+    

+    public void updateS(short bb) {

+        s = bb;

+        upS++;

+    }

+    

+    public void updateI(int bb) {

+        i = bb;

+        upI++;

+    }

+    

+    public void updateL(long bb) {

+        l = bb;

+        upL++;

+    }

+    

+    public void updateD(double bb) {

+        d = bb;

+        upD++;

+    }

+    

+    public void updateF(float bb) {

+        f = bb;

+        upF++;

+    }

+    

+    public void updateC(char bb) {

+        c = bb;

+        upC++;

+    }

+    

+    public void updateBool(boolean bb) {

+        bool = bb;

+        upBool++;

+    }

+    

+    public void updateBs(byte[] bb) {

+        bs = bb;

+        upBs++;

+    }

+    

+    public void updateSs(short[] bb) {

+        ss = bb;

+        upSs++;

+    }

+    

+    public void updateIs(int[] bb) {

+        is = bb;

+        upIs++;

+    }

+    

+    public void updateLs(long[] bb) {

+        ls = bb;

+        upLs++;

+    }

+    

+    public void updateDs(double[] bb) {

+        ds = bb;

+        upDs++;

+    }

+    

+    public void updateFs(float[] bb) {

+        fs = bb;

+        upFs++;

+    }

+    

+    public void updateCs(char[] bb) {

+        cs = bb;

+        upCs++;

+    }

+    

+    public void updateBools(boolean[] bb) {

+        bools = bb;

+        upBools++;

+    }

+    

+    public void updateStrings(String[] bb) {

+        strings = bb;

+        upStrings++;

+    }

+    

+    public void updateString(String bb) {

+        string = bb;

+        upString++;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckProvider.java
new file mode 100644
index 0000000..c05090d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckProvider.java
@@ -0,0 +1,95 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FilterCheckProvider implements CheckService, FooService {

+

+    private String m_toto;

+    

+    private int bind;

+    

+    private int unbind;

+    

+    public FilterCheckProvider(){

+        m_toto = "A";

+    }

+    

+    public boolean check() {

+        if (m_toto.equals("A")){

+            m_toto="B";

+            return true;

+        } else {

+            m_toto="A";

+            return false;

+        }

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("Bind", new Integer(bind-unbind));

+        return null;

+    }

+    

+    private void Bind() {

+        bind++;

+    }

+    private void Unbind() {

+        unbind++;

+    }

+

+    public boolean foo() {

+        return true;

+    }

+

+    public Properties fooProps() {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    public boolean getBoolean() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+

+    public double getDouble() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public int getInt() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public long getLong() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public Boolean getObject() {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckSubscriber.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckSubscriber.java
new file mode 100644
index 0000000..2c25e8c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FilterCheckSubscriber.java
@@ -0,0 +1,55 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.Nullable;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FilterCheckSubscriber implements CheckService {

+    

+    private FooService m_foo;

+    

+    private int binded;

+    

+    public FilterCheckSubscriber(){

+    }

+    

+    public boolean check() {

+        m_foo.foo();

+        return true;

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("Bind", new Integer(binded));

+        props.put("Nullable", new Boolean(m_foo instanceof Nullable));

+        return props;

+    }

+    

+    private void Bind() {

+        binded++;

+    }

+    private void Unbind() {

+        binded--;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooBarProviderType1.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooBarProviderType1.java
new file mode 100644
index 0000000..2b739b4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooBarProviderType1.java
@@ -0,0 +1,54 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FooBarProviderType1 implements FooService, BarService {

+

+	public boolean foo() {

+		return true;

+	}

+

+	public Properties fooProps() {

+		return new Properties();

+	}

+

+	public boolean bar() {

+		return true;

+	}

+

+	public Properties getProps() {

+		return new Properties();

+	}

+

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java
new file mode 100644
index 0000000..3fe9bad
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java
@@ -0,0 +1,117 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.BundleContext;

+

+public class FooProviderType1 implements FooService {

+	

+	private int m_bar;

+	private String m_foo;

+    

+    private BundleContext m_context;

+    

+    private static FooProviderType1 singleton;

+    private static int count = 0;

+    

+    private static FooProviderType1 singleton(BundleContext bc) {

+        if (singleton == null) {

+            count++;

+            singleton = new FooProviderType1(bc);

+        }

+        return singleton;

+    }

+    

+    public static FooProviderType1 several(BundleContext bc) {

+        count++;

+        return new FooProviderType1(bc);

+    }

+        

+    public FooProviderType1(BundleContext bc) {

+        if (bc ==null) {

+            throw new RuntimeException("Injected bundle context null");

+        }

+            m_context = bc;

+    }

+

+	public boolean foo() {

+		return true;

+	}

+

+	public Properties fooProps() {

+		Properties p = new Properties();

+		p.put("bar", new Integer(m_bar));

+        if(m_foo != null) {

+            p.put("foo", m_foo);

+        }

+        p.put("context", m_context);

+        

+        p.put("count", new Integer(count));

+		return p;

+	}

+    

+	public void testException() throws Exception {

+        String a = "foobarbaz";

+	    throw new Exception("foo"+a);

+    }

+    

+    public void testTry() {

+            String a = "foo";

+            a.charAt(0);

+    }

+    

+    public void testTry2(String s) {

+            String a = "foo";

+            a.charAt(0);

+    }

+    

+    private void nexttry(String  s) {

+        try {

+            s += "foo";

+        } catch(RuntimeException e) {

+            

+        }

+    }

+    

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+	

+	/**

+	 * Custom constructor.

+	 * @param bar

+	 * @param foo

+	 * @param bc

+	 */

+	public FooProviderType1(int bar, String foo, BundleContext bc) {

+	    m_bar = bar;

+	    m_foo = foo;

+	    m_context = bc;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java
new file mode 100644
index 0000000..39f3918
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java
@@ -0,0 +1,63 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FooProviderTypeDyn implements FooService {

+	

+	private int intProp;	

+	private String strProp;

+	private String[] strAProp;

+	private int[] intAProp;

+	private boolean boolProp;

+

+	public boolean foo() {

+		intProp = 3;

+		boolProp = true;

+		if(strProp.equals("foo")) { strProp = "bar"; }

+		else { strProp = "foo"; }

+		strAProp = new String[] {"foo", "bar", "baz"};

+		intAProp = new int[] {3, 2, 1};

+		return true;

+	}

+

+	public Properties fooProps() {

+		Properties p = new Properties();

+		p.put("intProp", new Integer(intProp));

+		p.put("boolProp", new Boolean(boolProp));

+		p.put("strProp", strProp);

+		p.put("strAProp", strAProp);

+		p.put("intAProp", intAProp);

+		return p;

+	}

+	

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn2.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn2.java
new file mode 100644
index 0000000..f5f233a
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn2.java
@@ -0,0 +1,58 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FooProviderTypeDyn2 implements FooService {

+	

+	private int intProp = 2;

+	private boolean boolProp = true;

+	private String strProp = "foo";

+	private String[] strAProp = new String[] {"foo", "bar"};

+	private int[] intAProp = new int[] {1, 2, 3};

+

+	public boolean foo() {

+		intAProp = null;

+		return true;

+	}

+

+	public Properties fooProps() {

+		Properties p = new Properties();

+		p.put("intProp", new Integer(intProp));

+		p.put("boolProp", new Boolean(boolProp));

+		p.put("strProp", strProp);

+		p.put("strAProp", strAProp);

+		p.put("intAProp", intAProp);

+		return p;

+	}

+	

+	public boolean getBoolean() { return true; }

+

+	public double getDouble() { return 1.0; }

+

+	public int getInt() { return 1; }

+

+	public long getLong() { return 1; }

+

+	public Boolean getObject() { return new Boolean(true); }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooServiceDefaultImpl.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooServiceDefaultImpl.java
new file mode 100644
index 0000000..8455c23
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooServiceDefaultImpl.java
@@ -0,0 +1,55 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class FooServiceDefaultImpl implements FooService {

+

+    public boolean foo() {

+        return false;

+    }

+

+    public Properties fooProps() {

+        return null;

+    }

+

+    public boolean getBoolean() {

+        return false;

+    }

+

+    public double getDouble() {

+        return 5;

+    }

+

+    public int getInt() {

+        return 5;

+    }

+

+    public long getLong() {

+        return 5;

+    }

+

+    public Boolean getObject() {

+        return null;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/LifecycleControllerTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/LifecycleControllerTest.java
new file mode 100644
index 0000000..c69bad5
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/LifecycleControllerTest.java
@@ -0,0 +1,49 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+

+public class LifecycleControllerTest implements CheckService {

+    

+    private boolean m_state = true;

+    private String m_conf;

+    

+    public void setConf(String newConf) {

+        if (newConf.equals("foo")) {

+            m_state = true;

+        } else {

+            m_state = false;

+        }

+    }

+

+    public boolean check() {

+        return m_state;

+    }

+

+    public Properties getProps() {

+       Properties props = new Properties();

+       props.put("conf", m_conf);

+       props.put("state", new Boolean(m_state));

+       return props;

+    }

+}

+

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Manipulation23Tester.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Manipulation23Tester.java
new file mode 100644
index 0000000..deff64e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Manipulation23Tester.java
@@ -0,0 +1,124 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import org.apache.felix.ipojo.test.scenarios.service.PrimitiveManipulationTestService;

+

+

+public class Manipulation23Tester implements PrimitiveManipulationTestService {

+	

+	// Integer types

+	byte b = 1;

+	short s = 1;

+	int i = 1;

+	long l = 1;

+	

+	// Floatting types

+	double d = 1.1;

+	float f = 1.1f;

+	

+	// Character

+	char c = 'a';

+	

+	// Boolean

+	boolean bool = false;

+	

+	// Integer arrays 

+	byte[] bs = new byte[] {0,1,2};

+	short[] ss = new short[] {0,1,2};

+	int[] is = new int[] {0,1,2};

+	long[] ls = new long[] {0,1,2};

+	

+	double[] ds = new double[] {0.0, 1.1, 2.2};

+	float[] fs = new float[] {0.0f, 1.1f, 2.2f};

+	

+	char[] cs = new char[] {'a', 'b', 'c'};

+	

+	boolean[] bools = new boolean[] {false, true, false};

+

+	public boolean getBoolean() { return bool; }

+

+	public boolean[] getBooleans() { return bools; }

+

+	public byte getByte() { return b; }

+

+	public byte[] getBytes() { return bs; }

+

+	public char getChar() { return c; }

+

+	public char[] getChars() { return cs; }

+

+	public double getDouble() { return d; }

+

+	public double[] getDoubles() { return ds; }

+

+	public float getFloat() { return f; }

+

+	public float[] getFloats() { return fs; }

+

+	public int getInt() { return i; }

+

+	public int[] getInts() { return is; }

+

+	public long getLong() { return l; }

+

+	public long[] getLongs() { return ls; }

+

+	public short getShort() { return s; }

+

+	public short[] getShorts() { return ss; }

+

+	public void setBoolean(boolean b) { this.bool = b; }

+

+	public void setBooleans(boolean[] bs) { this.bools = bs; }

+

+	public void setByte(byte b) { this.b = b; }

+

+	public void setBytes(byte[] bs) { this.bs = bs; }

+

+	public void setChar(char c) { this.c = c; }

+

+	public void setChars(char[] cs) { this.cs = cs; }

+

+	public void setDouble(double d) { this.d = d; }

+

+	public void setDoubles(double[] ds) { this.ds = ds; }

+

+	public void setFloat(float f) { this.f = f; }

+

+	public void setFloats(float[] fs) { this.fs = fs; }

+

+	public void setInt(int i) { this.i = i; }

+

+	public void setInts(int[] is) { this.is = is; }

+

+	public void setLong(long l) { this.l = l; }

+

+	public void setLongs(long[] ls) { this.ls = ls; }

+

+ 	public void setShort(short s) { this.s = s; }

+

+	public void setShorts(short[] ss) { this.ss = ss; }	

+	

+	// This method has been added to test an issue when autoboxing.

+	public void setLong(long l, String s) {

+	    this.l = l;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodCheckServiceProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodCheckServiceProvider.java
new file mode 100644
index 0000000..c069b09
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodCheckServiceProvider.java
@@ -0,0 +1,106 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+

+public class MethodCheckServiceProvider implements CheckService {

+	

+	FooService fs;

+    

+    BundleContext context;

+	

+	int simpleB = 0;

+	int objectB = 0;

+	int refB = 0;

+	int bothB = 0;

+	int simpleU = 0;

+	int objectU = 0;

+	int refU = 0;

+	int bothU = 0;

+	

+    

+    public MethodCheckServiceProvider(BundleContext bc) {

+        context = bc;

+    }

+

+	public boolean check() {

+		return fs.foo();

+	}

+

+	public Properties getProps() {

+		Properties props = new Properties();

+        if(fs != null) {

+            props.put("result", new Boolean(fs.foo()));

+            props.put("boolean", new Boolean(fs.getBoolean()));

+            props.put("int", new Integer(fs.getInt()));

+            props.put("long", new Long(fs.getLong()));

+            props.put("double", new Double(fs.getDouble()));

+        } else {

+            props.put("result", new Boolean(false));

+        }

+		props.put("voidB", new Integer(simpleB));

+		props.put("objectB", new Integer(objectB));

+		props.put("refB", new Integer(refB));

+		props.put("bothB", new Integer(bothB));

+		props.put("voidU", new Integer(simpleU));

+		props.put("objectU", new Integer(objectU));

+		props.put("refU", new Integer(refU));

+		props.put("bothU", new Integer(bothU));

+		

+		if(fs != null) {

+		    if(fs.getObject() != null) { props.put("object", fs.getObject()); }

+        }

+		

+		return props;

+	}

+	

+	protected void objectBind(FooService o) {

+		if(o != null && o instanceof FooService) { objectB++; }

+        fs = o;

+	}

+	protected void objectUnbind(FooService o) {

+		if(o != null && o instanceof FooService) { objectU++; }

+        fs = null;

+	}

+	

+	public void refBind(ServiceReference sr) {

+		if(sr != null) { refB++; }

+        fs = (FooService) context.getService(sr);

+	}

+	public void refUnbind(ServiceReference sr) {

+		if(sr != null) { refU++; }

+        context.ungetService(sr);

+        fs = null;

+	}

+	

+    protected void bothBind(FooService o, ServiceReference ref) {

+	    if(ref != null && o != null && o instanceof FooService) { bothB++; }

+	    fs = o;

+	}	

+    protected void bothUnbind(FooService o, ServiceReference ref) {

+	     if(ref != null && o != null && o instanceof FooService) { bothU++; }

+	     fs = null;

+	}

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodMultipleCheckService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodMultipleCheckService.java
new file mode 100644
index 0000000..32d4b1d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MethodMultipleCheckService.java
@@ -0,0 +1,153 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+

+public class MethodMultipleCheckService implements CheckService {

+

+	List fs = new ArrayList();

+	BundleContext context;

+

+    int simpleB = 0;

+

+    int objectB = 0;

+

+    int refB = 0;

+

+    int bothB = 0;

+

+    int simpleU = 0;

+

+    int objectU = 0;

+

+    int refU = 0;

+

+    int bothU = 0;

+    

+    public MethodMultipleCheckService(BundleContext bc) {

+        context = bc;

+    }

+

+	public boolean check() {

+            boolean r = fs.size() != 0;

+            for(int i = 0; i < fs.size(); i++) {

+                r = r & ((FooService) fs.get(i)).foo();

+            }

+            return r;

+	}

+	

+	private boolean getBoolean() {

+		return check();

+	}

+	

+	private int getInt() {

+		int r = 0;

+		for(int i = 0; i < fs.size(); i++) {

+			r = r + ((FooService) fs.get(i)).getInt();

+		}

+		return r;

+	}

+	

+	private long getLong() {

+		long r = 0;

+		for(int i = 0; i < fs.size(); i++) {

+			r = r + ((FooService) fs.get(i)).getLong();

+		}

+		return r;

+	}

+	

+	private double getDouble() {

+		double r = 0.0;

+		for(int i = 0; i < fs.size(); i++) {

+			r = r + ((FooService) fs.get(i)).getInt();

+		}

+		return r;

+	}

+	

+	protected Object doNothing(Object o, String s) { return null; }

+	

+//	private Object getObject() {

+//		boolean r = true;

+//		for(int i = 0; i < fs.length; i++) {

+//			r = r && ((Boolean) fs[i].getObject()).booleanValue();

+//		}

+//		return new Boolean(r);

+//	}

+

+	public Properties getProps() {

+		Properties props = new Properties();

+		props.put("result", new Boolean(check()));

+		props.put("voidB", new Integer(simpleB));

+		props.put("objectB", new Integer(objectB));

+		props.put("refB", new Integer(refB));

+        props.put("bothB", new Integer(bothB));

+        props.put("voidU", new Integer(simpleU));

+        props.put("objectU", new Integer(objectU));

+        props.put("refU", new Integer(refU));

+        props.put("bothU", new Integer(bothU));

+		props.put("boolean", new Boolean(getBoolean()));

+		props.put("int", new Integer(getInt()));

+		props.put("long", new Long(getLong()));

+		props.put("double", new Double(getDouble()));

+		

+		return props;

+	}

+	

+	public void objectBind(FooService o) {

+		if(o != null && o instanceof FooService) { objectB++; }

+        fs.add(o);

+	}

+	public void objectUnbind(FooService o) {

+		if(o != null && o instanceof FooService) { objectU++; }

+        fs.remove(o);

+	}

+	

+	public void refBind(ServiceReference sr) {

+		if(sr != null) { refB++; }

+        fs.add(context.getService(sr));

+	}

+	public void refUnbind(ServiceReference sr) {

+		if(sr != null) { refU++; }

+        fs.remove(context.getService(sr));

+        context.ungetService(sr);

+	}

+	

+	public void bothBind(FooService o, ServiceReference sr) {

+        if (o != null && o instanceof FooService && sr != null) {

+            fs.add(o);

+            bothB++;

+        }

+    }

+

+    public void bothUnbind(FooService o, ServiceReference sr) {

+        if (o != null && o instanceof FooService && sr != null) {

+            fs.remove(o);

+            bothU++;

+        }

+    }

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleCheckService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleCheckService.java
new file mode 100644
index 0000000..efbc972
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleCheckService.java
@@ -0,0 +1,158 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleCheckService implements CheckService {

+

+    FooService fs[];

+

+    int simpleB = 0;

+

+    int objectB = 0;

+

+    int refB = 0;

+

+    int bothB = 0;

+

+    int simpleU = 0;

+

+    int objectU = 0;

+

+    int refU = 0;

+

+    int bothU = 0;

+

+    public boolean check() {

+        boolean r = fs.length != 0;

+        for (int i = 0; i < fs.length; i++) {

+            r = r & fs[i].foo();

+        }

+        return r;

+    }

+

+    private boolean getBoolean() {

+        return check();

+    }

+

+    private int getInt() {

+        int r = 0;

+        for (int i = 0; i < fs.length; i++) {

+            r = r + fs[i].getInt();

+        }

+        return r;

+    }

+

+    private long getLong() {

+        long r = 0;

+        for (int i = 0; i < fs.length; i++) {

+            r = r + fs[i].getLong();

+        }

+        return r;

+    }

+

+    private double getDouble() {

+        double r = 0.0;

+        for (int i = 0; i < fs.length; i++) {

+            r = r + fs[i].getInt();

+        }

+        return r;

+    }

+

+    protected Object doNothing(Object o, String s) {

+        return null;

+    }

+

+    // private Object getObject() {

+    // boolean r = true;

+    // for(int i = 0; i < fs.length; i++) {

+    // r = r && ((Boolean) fs[i].getObject()).booleanValue();

+    // }

+    // return new Boolean(r);

+    // }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("result", new Boolean(check()));

+        props.put("voidB", new Integer(simpleB));

+        props.put("objectB", new Integer(objectB));

+        props.put("refB", new Integer(refB));

+        props.put("bothB", new Integer(bothB));

+        props.put("voidU", new Integer(simpleU));

+        props.put("objectU", new Integer(objectU));

+        props.put("refU", new Integer(refU));

+        props.put("bothU", new Integer(bothU));

+        props.put("boolean", new Boolean(getBoolean()));

+        props.put("int", new Integer(getInt()));

+        props.put("long", new Long(getLong()));

+        props.put("double", new Double(getDouble()));

+

+        return props;

+    }

+

+    public void voidBind() {

+        simpleB++;

+    }

+

+    public void voidUnbind() {

+        simpleU++;

+    }

+

+    public void objectBind(FooService o) {

+        if (o != null && o instanceof FooService) {

+            objectB++;

+        }

+    }

+

+    public void objectUnbind(FooService o) {

+        if (o != null && o instanceof FooService) {

+            objectU++;

+        }

+    }

+

+    public void refBind(ServiceReference sr) {

+        if (sr != null) {

+            refB++;

+        }

+    }

+

+    public void refUnbind(ServiceReference sr) {

+        if (sr != null) {

+            refU++;

+        }

+    }

+

+    public void bothBind(FooService o, ServiceReference sr) {

+        if (o != null && o instanceof FooService && sr != null) {

+            bothB++;

+        }

+    }

+

+    public void bothUnbind(FooService o, ServiceReference sr) {

+        if (o != null && o instanceof FooService && sr != null) {

+            bothU++;

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleFilterCheckSubscriber.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleFilterCheckSubscriber.java
new file mode 100644
index 0000000..6b7370e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/MultipleFilterCheckSubscriber.java
@@ -0,0 +1,56 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class MultipleFilterCheckSubscriber implements CheckService {

+    

+    private FooService[] m_foo;

+    

+    private int binded;

+    

+    public MultipleFilterCheckSubscriber(){

+    }

+    

+    public boolean check() {

+        for (int i = 0; i < m_foo.length; i++) {

+            m_foo[i].foo();

+        }

+        return true;

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("Bind", new Integer(binded));

+        props.put("Size",  new Integer(m_foo.length));

+        return props;

+    }

+    

+    private void Bind() {

+        binded++;

+    }

+    private void Unbind() {

+        binded--;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentClass.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentClass.java
new file mode 100644
index 0000000..f7fb580
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentClass.java
@@ -0,0 +1,51 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+public class ParentClass {

+    

+    public void parentStart() {

+        

+    }

+    

+    public void parentStop() {

+        

+    }

+	

+	protected String[] strings;

+	

+	protected String string;

+	

+	protected int upStrings;

+	

+	protected int upString;

+	

+	public void updateStrings(String[] bb) {

+        strings = bb;

+        upStrings++;

+    }

+    

+    public void updateString(String bb) {

+        string = bb;

+        upString++;

+    }

+	

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentConfigurableCheckServiceProvider.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentConfigurableCheckServiceProvider.java
new file mode 100644
index 0000000..304b83f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ParentConfigurableCheckServiceProvider.java
@@ -0,0 +1,194 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+

+public class ParentConfigurableCheckServiceProvider extends ParentClass implements CheckService {

+    

+    // Integer types

+    byte b;

+    short s;

+    int i;

+    long l;

+    

+    // Floatting types

+    double d;

+    float f;

+    

+    // Character

+    char c;

+    

+    // Boolean

+    boolean bool;

+    

+    // Integer arrays 

+    byte[] bs;

+    short[] ss;

+    int[] is;

+    long[] ls;

+    

+    double[] ds;

+    float[] fs;

+    

+    char[] cs;

+    

+    boolean[] bools;

+    

+    //String string;

+    //String[] strings;

+    

+    int upB, upS, upI, upL, upD, upF, upC, upBool, upBs, upSs, upIs, upLs, upDs, upFs, upCs, upBools/*, upString, upStrings*/;

+    

+

+    public boolean check() {

+        return true;

+    }

+

+    public Properties getProps() {

+        Properties props = new Properties();

+        props.put("b", new Byte(b));

+        props.put("s", new Short(s));

+        props.put("i", new Integer(i));

+        props.put("l", new Long(l));

+        props.put("d", new Double(d));

+        props.put("f", new Float(f));

+        props.put("c", new Character(c));

+        props.put("bool", new Boolean(bool));

+        

+        props.put("bs", bs);

+        props.put("ss", ss);

+        props.put("is", is);

+        props.put("ls", ls);

+        props.put("ds", ds);

+        props.put("fs", fs);

+        props.put("cs", cs);

+        props.put("bools", bools);

+        

+        props.put("upb", new Integer(upB));

+        props.put("ups", new Integer(upS));

+        props.put("upi", new Integer(upI));

+        props.put("upl", new Integer(upL));

+        props.put("upd", new Integer(upD));

+        props.put("upf", new Integer(upF));

+        props.put("upc", new Integer(upC));

+        props.put("upbool", new Integer(upBool));

+        

+        props.put("upbs", new Integer(upBs));

+        props.put("upss", new Integer(upSs));

+        props.put("upis", new Integer(upIs));

+        props.put("upls", new Integer(upLs));

+        props.put("upds", new Integer(upDs));

+        props.put("upfs", new Integer(upFs));

+        props.put("upcs", new Integer(upCs));

+        props.put("upbools", new Integer(upBools));

+        

+        props.put("string", string);

+        props.put("strings", strings);

+        props.put("upstring", new Integer(upString));

+        props.put("upstrings", new Integer(upStrings));

+        

+        return props;

+    }

+    

+    public void updateB(byte bb) {

+        b = bb;

+        upB++;

+    }

+    

+    public void updateS(short bb) {

+        s = bb;

+        upS++;

+    }

+    

+    public void updateI(int bb) {

+        i = bb;

+        upI++;

+    }

+    

+    public void updateL(long bb) {

+        l = bb;

+        upL++;

+    }

+    

+    public void updateD(double bb) {

+        d = bb;

+        upD++;

+    }

+    

+    public void updateF(float bb) {

+        f = bb;

+        upF++;

+    }

+    

+    public void updateC(char bb) {

+        c = bb;

+        upC++;

+    }

+    

+    public void updateBool(boolean bb) {

+        bool = bb;

+        upBool++;

+    }

+    

+    public void updateBs(byte[] bb) {

+        bs = bb;

+        upBs++;

+    }

+    

+    public void updateSs(short[] bb) {

+        ss = bb;

+        upSs++;

+    }

+    

+    public void updateIs(int[] bb) {

+        is = bb;

+        upIs++;

+    }

+    

+    public void updateLs(long[] bb) {

+        ls = bb;

+        upLs++;

+    }

+    

+    public void updateDs(double[] bb) {

+        ds = bb;

+        upDs++;

+    }

+    

+    public void updateFs(float[] bb) {

+        fs = bb;

+        upFs++;

+    }

+    

+    public void updateCs(char[] bb) {

+        cs = bb;

+        upCs++;

+    }

+    

+    public void updateBools(boolean[] bb) {

+        bools = bb;

+        upBools++;

+    }

+    

+    

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation1.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation1.java
new file mode 100644
index 0000000..3ffab2f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation1.java
@@ -0,0 +1,45 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.inherited;

+

+import org.apache.felix.ipojo.test.scenarios.service.ChildInterface;

+

+public class ProcessImplementation1 implements ChildInterface {

+

+    public void processChild() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent1() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParentParent() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent2() {

+        // TODO Auto-generated method stub

+

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation2.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation2.java
new file mode 100644
index 0000000..49e9267
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation2.java
@@ -0,0 +1,44 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.inherited;

+

+

+public class ProcessImplementation2 extends ProcessParentImplementation {

+

+    public void processChild() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent1() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParentParent() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent2() {

+        // TODO Auto-generated method stub

+

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation3.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation3.java
new file mode 100644
index 0000000..cc576d8
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessImplementation3.java
@@ -0,0 +1,82 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.inherited;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class ProcessImplementation3 extends ProcessParentImplementation  implements FooService {

+

+    public void processChild() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent1() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParentParent() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public void processParent2() {

+        // TODO Auto-generated method stub

+

+    }

+

+    public boolean foo() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+

+    public Properties fooProps() {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+    public boolean getBoolean() {

+        // TODO Auto-generated method stub

+        return false;

+    }

+

+    public double getDouble() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public int getInt() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public long getLong() {

+        // TODO Auto-generated method stub

+        return 0;

+    }

+

+    public Boolean getObject() {

+        // TODO Auto-generated method stub

+        return null;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessParentImplementation.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessParentImplementation.java
new file mode 100644
index 0000000..69ebace
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/component/inherited/ProcessParentImplementation.java
@@ -0,0 +1,46 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.component.inherited;

+

+import org.apache.felix.ipojo.test.scenarios.service.ChildInterface;

+

+public class ProcessParentImplementation implements ChildInterface {

+

+    public void processChild() {

+        // TODO Auto-generated method stub

+        

+    }

+

+    public void processParent1() {

+        // TODO Auto-generated method stub

+        

+    }

+

+    public void processParentParent() {

+        // TODO Auto-generated method stub

+        

+    }

+

+    public void processParent2() {

+        // TODO Auto-generated method stub

+        

+    }

+

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java
new file mode 100644
index 0000000..012f642
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java
@@ -0,0 +1,40 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ConfigurationTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Configuration Test Suite", bc);

+		ots.addTestSuite(SimpleProperties.class);

+		ots.addTestSuite(DynamicallyConfigurableProperties.class);

+		ots.addTestSuite(TestFieldProperties.class);

+		ots.addTestSuite(TestMethodProperties.class);

+		ots.addTestSuite(TestBothProperties.class);

+		ots.addTestSuite(TestSuperMethodProperties.class);

+		

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/DynamicallyConfigurableProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/DynamicallyConfigurableProperties.java
new file mode 100644
index 0000000..204d1b4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/DynamicallyConfigurableProperties.java
@@ -0,0 +1,228 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.ConfigurationException;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+public class DynamicallyConfigurableProperties extends OSGiTestCase {

+

+	ComponentInstance instance;

+	

+	public void setUp() {

+		String type = "FooProviderType-3";

+		

+		Properties p1 = new Properties();

+		p1.put("name", "instance");

+		p1.put("foo", "foo");

+		p1.put("bar", "2");

+		p1.put("baz", "baz");

+		instance = Utils.getComponentInstance(context, type, p1);

+	}

+	

+	public void tearDown() {

+		instance.dispose();

+		instance = null;

+	}

+	

+	public void testStatic() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

+		String fooP = (String) fooRef.getProperty("foo");

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -1", fooP, "foo");

+		assertEquals("Check bar equality -1", barP, new Integer(2));

+		assertEquals("Check baz equality -1", bazP, "baz");

+		

+		ServiceReference msRef = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), instance.getFactory().getName());

+		assertNotNull("Check ManagedServiceFactory availability", msRef);

+		

+		

+		// Configuration of baz

+		Properties conf = new Properties();

+		conf.put("baz", "zab");

+		conf.put("bar", new Integer(2));

+		conf.put("foo", "foo");

+		ManagedServiceFactory ms = (ManagedServiceFactory) context.getService(msRef);

+		try {

+			ms.updated(instance.getInstanceName(), conf);

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Recheck props

+		fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		fooP = (String) fooRef.getProperty("foo");

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -2", fooP, "foo");

+		assertEquals("Check bar equality -2", barP, new Integer(2));

+		assertEquals("Check baz equality -2", bazP, "zab");

+		context.ungetService(msRef);

+	}

+	

+	public void testDynamic() {

+    	ServiceReference fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+    	assertNotNull("Check FS availability", fooRef);

+    	

+    	String fooP = (String) fooRef.getProperty("foo");

+    	Integer barP = (Integer) fooRef.getProperty("bar");

+    	String bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "foo");

+    	assertEquals("Check bar equality", barP, new Integer(2));

+    	assertEquals("Check baz equality", bazP, "baz");

+    	

+    	ServiceReference msRef = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), instance.getFactory().getName());

+    	assertNotNull("Check ManagedServiceFactory availability", msRef);

+    	

+    	// Configuration of baz

+    	Properties conf = new Properties();

+    	conf.put("baz", "zab");

+    	conf.put("foo", "oof");

+    	conf.put("bar", new Integer(0));

+    	ManagedServiceFactory ms = (ManagedServiceFactory) context.getService(msRef);

+    	try {

+    		ms.updated(instance.getInstanceName(), conf);

+    	} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+    	

+    	// Recheck props

+    	fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+    	fooP = (String) fooRef.getProperty("foo");

+    	barP = (Integer) fooRef.getProperty("bar");

+    	bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "oof");

+    	assertEquals("Check bar equality", barP, new Integer(0));

+    	assertEquals("Check baz equality", bazP, "zab");

+    	

+    	// Check field value

+    	FooService fs = (FooService) context.getService(fooRef);

+    	Properties p = fs.fooProps();

+    	fooP = (String) p.get("foo");

+    	barP = (Integer) p.get("bar");

+    	

+    	assertEquals("Check foo field equality", fooP, "oof");

+    	assertEquals("Check bar field equality", barP, new Integer(0));

+    	

+    	context.ungetService(fooRef);

+    	context.ungetService(msRef);

+    }

+

+    public void testDynamicString() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

+		

+		String fooP = (String) fooRef.getProperty("foo");

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		

+		assertEquals("Check foo equality", fooP, "foo");

+		assertEquals("Check bar equality", barP, new Integer(2));

+		assertEquals("Check baz equality", bazP, "baz");

+		

+		ServiceReference msRef = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), instance.getFactory().getName());

+		assertNotNull("Check ManagedServiceFactory availability", msRef);

+		

+		// Configuration of baz

+		Properties conf = new Properties();

+		conf.put("baz", "zab");

+		conf.put("foo", "oof");

+		conf.put("bar", "0");

+		ManagedServiceFactory ms = (ManagedServiceFactory) context.getService(msRef);

+		try {

+			ms.updated(instance.getInstanceName(), conf);

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Recheck props

+		fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		fooP = (String) fooRef.getProperty("foo");

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		

+		assertEquals("Check foo equality", fooP, "oof");

+		assertEquals("Check bar equality", barP, new Integer(0));

+		assertEquals("Check baz equality", bazP, "zab");

+		

+		// Check field value

+		FooService fs = (FooService) context.getService(fooRef);

+		Properties p = fs.fooProps();

+		fooP = (String) p.get("foo");

+		barP = (Integer) p.get("bar");

+		

+		assertEquals("Check foo field equality", fooP, "oof");

+		assertEquals("Check bar field equality", barP, new Integer(0));

+		

+		context.ungetService(fooRef);

+		context.ungetService(msRef);

+	}

+	

+	public void testPropagation() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

+		

+		String fooP = (String) fooRef.getProperty("foo");

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		

+		assertEquals("Check foo equality", fooP, "foo");

+		assertEquals("Check bar equality", barP, new Integer(2));

+		assertEquals("Check baz equality", bazP, "baz");

+		

+		ServiceReference msRef = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), instance.getFactory().getName());

+		assertNotNull("Check ManagedServiceFactory availability", msRef);

+		

+		// Configuration of baz

+		Properties conf = new Properties();

+		conf.put("baz", "zab");

+		conf.put("foo", "foo");

+		conf.put("bar", new Integer(2));

+		conf.put("propagated1", "propagated");

+		conf.put("propagated2", new Integer(1));

+		ManagedServiceFactory ms = (ManagedServiceFactory) context.getService(msRef);

+		try {

+			ms.updated(instance.getInstanceName(), conf);

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Recheck props

+		fooRef = Utils.getServiceReferenceByName(context, FooService.class.getName(), instance.getInstanceName());

+		fooP = (String) fooRef.getProperty("foo");

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		assertNotNull("Check the propagated1 existency", fooRef.getProperty("propagated1"));

+		String prop1 = (String) fooRef.getProperty("propagated1");

+		assertNotNull("Check the propagated2 existency", fooRef.getProperty("propagated2"));

+		Integer prop2 = (Integer) fooRef.getProperty("propagated2");

+		

+		assertEquals("Check foo equality", fooP, "foo");

+		assertEquals("Check bar equality", barP, new Integer(2));

+		assertEquals("Check baz equality", bazP, "zab");

+		assertEquals("Check propagated1 equality", prop1, "propagated");

+		assertEquals("Check propagated2 equality", prop2, new Integer(1));

+		

+		context.ungetService(msRef);

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/SimpleProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/SimpleProperties.java
new file mode 100644
index 0000000..318304e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/SimpleProperties.java
@@ -0,0 +1,171 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleProperties extends OSGiTestCase {

+	

+	ComponentInstance fooProvider1;

+	ComponentInstance fooProvider2;

+	

+	public void setUp() {

+		String type = "FooProviderType-Conf";

+		

+		Properties p1 = new Properties();

+		p1.put("name", "FooProvider-1");

+		fooProvider1 = Utils.getComponentInstance(context, type, p1);

+		

+		Properties p2 = new Properties();

+		p2.put("name", "FooProvider-2");

+		p2.put("int", new Integer(4));

+		p2.put("boolean", new Boolean(false));

+		p2.put("string", new String("bar"));

+		p2.put("strAProp", new String[] {"bar", "foo"});

+		p2.put("intAProp", new int[] {1, 2, 3});

+		fooProvider2 = Utils.getComponentInstance(context, type, p2);

+	}

+	

+	public void tearDown() {

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testComponentTypeConfiguration() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check FooService availability", ref);

+		FooService fs = (FooService) context.getService(ref);

+		Properties toCheck = fs.fooProps();

+		

+		Integer intProp = (Integer) toCheck.get("intProp");

+		Boolean boolProp = (Boolean) toCheck.get("boolProp");

+		String strProp = (String) toCheck.get("strProp");

+		String[] strAProp = (String[]) toCheck.get("strAProp");

+		int[] intAProp = (int[]) toCheck.get("intAProp");

+		

+		assertEquals("Check intProp equality (1)", intProp, new Integer(2));

+		assertEquals("Check longProp equality (1)", boolProp, new Boolean(false));

+		assertEquals("Check strProp equality (1)", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity (1)", strAProp);

+		String[] v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (1) : " + strAProp[i] + " != " + v[i]); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (1) : " + intAProp[i] + " != " + v2[i]); }

+		}

+		

+		// change the field value

+		assertTrue("Invoke the fs service", fs.foo());

+		toCheck = fs.fooProps();

+		

+		

+		//	Re-check the property (change)

+		intProp = (Integer) toCheck.get("intProp");

+		boolProp = (Boolean) toCheck.get("boolProp");

+		strProp = (String) toCheck.get("strProp");

+		strAProp = (String[]) toCheck.get("strAProp");

+		intAProp = (int[]) toCheck.get("intAProp");

+		

+		assertEquals("Check intProp equality (2) ("+intProp+")", intProp, new Integer(3));

+		assertEquals("Check longProp equality (2)", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality (2)", strProp, new String("bar"));

+		assertNotNull("Check strAProp not nullity (2)", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (2)"); }

+		}

+		assertNotNull("Check intAProp not nullity (2)", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (2) : " + intAProp[i] + " != " + v2[i]); }

+		}

+		

+		fs = null;

+		context.ungetService(ref);

+	}

+	

+	public void testInstanceConfiguration() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-2");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		FooService fs = (FooService) context.getService(sr);

+		Properties toCheck = fs.fooProps();

+		

+		// Check service properties

+		Integer intProp = (Integer) toCheck.get("intProp");

+		Boolean boolProp = (Boolean) toCheck.get("boolProp");

+		String strProp = (String) toCheck.get("strProp");

+		String[] strAProp = (String[]) toCheck.get("strAProp");

+		int[] intAProp = (int[]) toCheck.get("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(4));

+		assertEquals("Check longProp equality", boolProp, new Boolean(false));

+		assertEquals("Check strProp equality", strProp, new String("bar"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"bar", "foo"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		

+		assertTrue("invoke fs", fs.foo());

+		toCheck = fs.fooProps();

+		

+		// Re-check the property (change)

+		intProp = (Integer) toCheck.get("intProp");

+		boolProp = (Boolean) toCheck.get("boolProp");

+		strProp = (String) toCheck.get("strProp");

+		strAProp = (String[]) toCheck.get("strAProp");

+		intAProp = (int[]) toCheck.get("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(3));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		fs = null;

+		context.ungetService(sr);	

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestBothProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestBothProperties.java
new file mode 100644
index 0000000..695d61e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestBothProperties.java
@@ -0,0 +1,618 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestBothProperties extends OSGiTestCase {

+    

+    ComponentInstance instance;

+

+    

+    public void setUp() {

+        Factory fact = Utils.getFactoryByName(context, "BothConfigurableCheckService");

+        Properties props = new Properties();

+        props.put("name", "under-test");

+        props.put("b", "1");

+        props.put("s", "1");

+        props.put("i", "1");

+        props.put("l", "1");

+        props.put("d", "1");

+        props.put("f", "1");

+        props.put("c", "a");

+        props.put("bool", "true");

+        props.put("bs", "{1,2,3}");

+        props.put("ss", "{1,2,3}");

+        props.put("is", "{1,2,3}");

+        props.put("ls", "{1,2,3}");

+        props.put("ds", "{1,2,3}");

+        props.put("fs", "{1,2,3}");

+        props.put("cs", "{a,b,c}");

+        props.put("bools", "{true,true,true}");

+        props.put("string", "foo");

+        props.put("strings", "{foo, bar, baz}");

+        

+        try {

+            instance = fact.createComponentInstance(props);

+        } catch(Exception e) {

+           fail("Cannot create the under-test instance : " + e.getMessage());

+        }

+        

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        instance = null;

+    }

+    

+    public void testConfigurationPrimitive() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationPrimitiveArrays() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveArraysString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationObj() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upstring", upString, new Integer(2));

+        assertEquals("2) Check upstrings", upStrings, new Integer(2));

+    }

+

+    public void testConfigurationObjString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upstring", upString, new Integer(2));

+        assertEquals("2) Check upstrings", upStrings, new Integer(2));

+    }

+    

+    private void reconfigure() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", new Byte("2"));

+        props2.put("s", new Short("2"));

+        props2.put("i", new Integer("2"));

+        props2.put("l", new Long("2"));

+        props2.put("d", new Double("2"));

+        props2.put("f", new Float("2"));

+        props2.put("c", new Character('b'));

+        props2.put("bool", new Boolean(false));

+        props2.put("bs", new byte[]{(byte)3,(byte)2,(byte)1});

+        props2.put("ss", new short[]{(short)3,(short)2,(short)1});

+        props2.put("is", new int[]{3,2,1});

+        props2.put("ls", new long[]{3,2,1});

+        props2.put("ds", new double[]{3,2,1});

+        props2.put("fs", new float[]{3,2,1});

+        props2.put("cs", new char[]{'c','b','a'});

+        props2.put("bools", new boolean[]{false,false,false});

+        props2.put("string", "bar");

+        props2.put("strings", new String[]{"baz", "bar", "foo"});

+        

+        instance.reconfigure(props2);

+    }

+    

+    private void reconfigureString() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", "2");

+        props2.put("s", "2");

+        props2.put("i", "2");

+        props2.put("l", "2");

+        props2.put("d", "2");

+        props2.put("f", "2");

+        props2.put("c", "b");

+        props2.put("bool", "false");

+        props2.put("bs", "{3, 2,1}");

+        props2.put("ss", "{3, 2,1}");

+        props2.put("is", "{3, 2,1}");

+        props2.put("ls", "{3, 2,1}");

+        props2.put("ds", "{3, 2,1}");

+        props2.put("fs", "{3, 2,1}");

+        props2.put("cs", "{c, b , a}");

+        props2.put("bools", "{false,false,false}");

+        props2.put("string", "bar");

+        props2.put("strings", "{baz, bar, foo}");

+        

+        instance.reconfigure(props2);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestFieldProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestFieldProperties.java
new file mode 100644
index 0000000..b49c823
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestFieldProperties.java
@@ -0,0 +1,449 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestFieldProperties extends OSGiTestCase {

+    

+    ComponentInstance instance;

+    

+    public void setUp() {

+        Factory fact = Utils.getFactoryByName(context, "FieldConfigurableCheckService");

+        Properties props = new Properties();

+        props.put("name", "under-test");

+        props.put("b", "1");

+        props.put("s", "1");

+        props.put("i", "1");

+        props.put("l", "1");

+        props.put("d", "1");

+        props.put("f", "1");

+        props.put("c", "a");

+        props.put("bool", "true");

+        props.put("bs", "{1,2,3}");

+        props.put("ss", "{1,2,3}");

+        props.put("is", "{1,2,3}");

+        props.put("ls", "{1,2,3}");

+        props.put("ds", "{1,2,3}");

+        props.put("fs", "{1,2,3}");

+        props.put("cs", "{a,b,c}");

+        props.put("bools", "{true,true,true}");

+        props.put("string", "foo");

+        props.put("strings", "{foo, bar, baz}");

+        

+        try {

+            instance = fact.createComponentInstance(props);

+        } catch(Exception e) {

+           fail("Cannot create the under-test instance : " + e.getMessage());

+        }

+        

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        instance = null;

+    }

+    

+    public void testConfigurationPrimitive() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+    }

+

+    public void testConfigurationPrimitiveString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+    }

+    

+    public void testConfigurationPrimitiveArrays() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+    }

+

+    public void testConfigurationPrimitiveArraysString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+    }

+    

+    public void testConfigurationObj() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+    }

+

+    public void testConfigurationObjString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+    }

+    

+    private void reconfigure() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", new Byte("2"));

+        props2.put("s", new Short("2"));

+        props2.put("i", new Integer("2"));

+        props2.put("l", new Long("2"));

+        props2.put("d", new Double("2"));

+        props2.put("f", new Float("2"));

+        props2.put("c", new Character('b'));

+        props2.put("bool", new Boolean(false));

+        props2.put("bs", new byte[]{(byte)3,(byte)2,(byte)1});

+        props2.put("ss", new short[]{(short)3,(short)2,(short)1});

+        props2.put("is", new int[]{3,2,1});

+        props2.put("ls", new long[]{3,2,1});

+        props2.put("ds", new double[]{3,2,1});

+        props2.put("fs", new float[]{3,2,1});

+        props2.put("cs", new char[]{'c','b','a'});

+        props2.put("bools", new boolean[]{false,false,false});

+        props2.put("string", "bar");

+        props2.put("strings", new String[]{"baz", "bar", "foo"});

+        

+        instance.reconfigure(props2);

+    }

+    

+    private void reconfigureString() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", "2");

+        props2.put("s", "2");

+        props2.put("i", "2");

+        props2.put("l", "2");

+        props2.put("d", "2");

+        props2.put("f", "2");

+        props2.put("c", "b");

+        props2.put("bool", "false");

+        props2.put("bs", "{3, 2,1}");

+        props2.put("ss", "{3, 2,1}");

+        props2.put("is", "{3, 2,1}");

+        props2.put("ls", "{3, 2,1}");

+        props2.put("ds", "{3, 2,1}");

+        props2.put("fs", "{3, 2,1}");

+        props2.put("cs", "{c, b , a}");

+        props2.put("bools", "{false,false,false}");

+        props2.put("string", "bar");

+        props2.put("strings", "{baz, bar, foo}");

+        

+        instance.reconfigure(props2);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestMethodProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestMethodProperties.java
new file mode 100644
index 0000000..7e1dcea
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestMethodProperties.java
@@ -0,0 +1,1145 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestMethodProperties extends OSGiTestCase {

+    

+    ComponentInstance instance;

+    

+    ComponentInstance instance2;

+

+    public void setUp() {

+        Factory fact = Utils.getFactoryByName(context, "MethodConfigurableCheckService");

+        Properties props = new Properties();

+        props.put("name", "under-test");

+        props.put("b", "1");

+        props.put("s", "1");

+        props.put("i", "1");

+        props.put("l", "1");

+        props.put("d", "1");

+        props.put("f", "1");

+        props.put("c", "a");

+        props.put("bool", "true");

+        props.put("bs", "{1,2,3}");

+        props.put("ss", "{1,2,3}");

+        props.put("is", "{1,2,3}");

+        props.put("ls", "{1,2,3}");

+        props.put("ds", "{1,2,3}");

+        props.put("fs", "{1,2,3}");

+        props.put("cs", "{a,b,c}");

+        props.put("bools", "{true,true,true}");

+        props.put("string", "foo");

+        props.put("strings", "{foo, bar, baz}");

+        

+        try {

+            instance = fact.createComponentInstance(props);

+        } catch(Exception e) {

+           fail("Cannot create the under-test instance : " + e.getMessage());

+        }

+        

+        Properties props2 = new Properties();

+        props2.put("name", "under-test-2");

+        props2.put("b", new Byte("1"));

+        props2.put("s", new Short("1"));

+        props2.put("i", new Integer("1"));

+        props2.put("l", new Long("1"));

+        props2.put("d", new Double("1"));

+        props2.put("f", new Float("1"));

+        props2.put("c", new Character('a'));

+        props2.put("bool", new Boolean(true));

+        props2.put("bs", new byte[] {1,2,3});

+        props2.put("ss", new short[] {1,2,3});

+        props2.put("is", new int[] {1,2,3});

+        props2.put("ls", new long[] {1,2,3});

+        props2.put("ds", new double[] {1,2,3});

+        props2.put("fs", new float[] {1,2,3});

+        props2.put("cs", new char[] {'a','b','c'});

+        props2.put("bools", new boolean[] {true,true,true});

+        props2.put("string", "foo");

+        props2.put("strings", new String[] {"foo", "bar", "baz"});

+        

+        try {

+            instance2 = fact.createComponentInstance(props2);

+        } catch(Exception e) {

+           e.printStackTrace();

+           fail("Cannot create the under-test instance 2 : " + e.getMessage());

+        }

+        

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        instance2.dispose();

+        instance = null;

+        instance2 = null;

+    }

+    

+    public void testConfigurationPrimitive() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationPrimitiveArrays() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveArraysString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationObj() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigure(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+

+    public void testConfigurationObjString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigureString(instance);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+    

+    public void testConfigurationPrimitive2() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitive2String() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationPrimitiveArrays2() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveArrays2String() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationObj2() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigure(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+

+    public void testConfigurationObj2String() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigureString(instance2);

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+    

+    private void reconfigure(ComponentInstance ci) {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", new Byte("2"));

+        props2.put("s", new Short("2"));

+        props2.put("i", new Integer("2"));

+        props2.put("l", new Long("2"));

+        props2.put("d", new Double("2"));

+        props2.put("f", new Float("2"));

+        props2.put("c", new Character('b'));

+        props2.put("bool", new Boolean(false));

+        props2.put("bs", new byte[]{(byte)3,(byte)2,(byte)1});

+        props2.put("ss", new short[]{(short)3,(short)2,(short)1});

+        props2.put("is", new int[]{3,2,1});

+        props2.put("ls", new long[]{3,2,1});

+        props2.put("ds", new double[]{3,2,1});

+        props2.put("fs", new float[]{3,2,1});

+        props2.put("cs", new char[]{'c','b','a'});

+        props2.put("bools", new boolean[]{false,false,false});

+        props2.put("string", "bar");

+        props2.put("strings", new String[]{"baz", "bar", "foo"});

+        

+        ci.reconfigure(props2);

+    }

+    

+    private void reconfigureString(ComponentInstance ci) {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", "2");

+        props2.put("s", "2");

+        props2.put("i", "2");

+        props2.put("l", "2");

+        props2.put("d", "2");

+        props2.put("f", "2");

+        props2.put("c", "b");

+        props2.put("bool", "false");

+        props2.put("bs", "{3, 2,1}");

+        props2.put("ss", "{3, 2,1}");

+        props2.put("is", "{3, 2,1}");

+        props2.put("ls", "{3, 2,1}");

+        props2.put("ds", "{3, 2,1}");

+        props2.put("fs", "{3, 2,1}");

+        props2.put("cs", "{c, b , a}");

+        props2.put("bools", "{false,false,false}");

+        props2.put("string", "bar");

+        props2.put("strings", "{baz, bar, foo}");

+        

+        ci.reconfigure(props2);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestSuperMethodProperties.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestSuperMethodProperties.java
new file mode 100644
index 0000000..c7b322b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/TestSuperMethodProperties.java
@@ -0,0 +1,617 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class TestSuperMethodProperties extends OSGiTestCase {

+    

+    ComponentInstance instance;

+

+    public void setUp() {

+        Factory fact = Utils.getFactoryByName(context, "ParentMethodConfigurableCheckService");

+        Properties props = new Properties();

+        props.put("name", "under-test");

+        props.put("b", "1");

+        props.put("s", "1");

+        props.put("i", "1");

+        props.put("l", "1");

+        props.put("d", "1");

+        props.put("f", "1");

+        props.put("c", "a");

+        props.put("bool", "true");

+        props.put("bs", "{1,2,3}");

+        props.put("ss", "{1,2,3}");

+        props.put("is", "{1,2,3}");

+        props.put("ls", "{1,2,3}");

+        props.put("ds", "{1,2,3}");

+        props.put("fs", "{1,2,3}");

+        props.put("cs", "{a,b,c}");

+        props.put("bools", "{true,true,true}");

+        props.put("string", "foo");

+        props.put("strings", "{foo, bar, baz}");

+        

+        try {

+            instance = fact.createComponentInstance(props);

+        } catch (Exception e) {

+           fail("Cannot create the under-test instance : " + e.getMessage());

+        }

+        

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        instance = null;

+    }

+    

+    public void testConfigurationPrimitive() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        Byte b = (Byte) props.get("b");

+        Short s = (Short) props.get("s");

+        Integer i = (Integer) props.get("i");

+        Long l = (Long) props.get("l");

+        Double d = (Double) props.get("d");

+        Float f = (Float) props.get("f");

+        Character c = (Character) props.get("c");

+        Boolean bool = (Boolean) props.get("bool");

+                

+        assertEquals("Check b", b, new Byte("1"));

+        assertEquals("Check s", s, new Short("1"));

+        assertEquals("Check i", i, new Integer("1"));

+        assertEquals("Check l", l, new Long("1"));

+        assertEquals("Check d", d, new Double("1"));

+        assertEquals("Check f", f, new Float("1"));

+        assertEquals("Check c", c, new Character('a'));

+        assertEquals("Check bool", bool, new Boolean("true"));

+        

+        Integer upb = (Integer) props.get("upb");

+        Integer ups = (Integer) props.get("ups");

+        Integer upi = (Integer) props.get("upi");

+        Integer upl = (Integer) props.get("upl");

+        Integer upd = (Integer) props.get("upd");

+        Integer upf = (Integer) props.get("upf");

+        Integer upc = (Integer) props.get("upc");

+        Integer upbool = (Integer) props.get("upbool");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (Byte) props.get("b");

+        s = (Short) props.get("s");

+        i = (Integer) props.get("i");

+        l = (Long) props.get("l");

+        d = (Double) props.get("d");

+        f = (Float) props.get("f");

+        c = (Character) props.get("c");

+        bool = (Boolean) props.get("bool");

+        

+        assertEquals("2) Check b ("+b+")", b, new Byte("2"));

+        assertEquals("2) Check s", s, new Short("2"));

+        assertEquals("2) Check i", i, new Integer("2"));

+        assertEquals("2) Check l", l, new Long("2"));

+        assertEquals("2) Check d", d, new Double("2"));

+        assertEquals("2) Check f", f, new Float("2"));

+        assertEquals("2) Check c", c, new Character('b'));

+        assertEquals("2) Check bool", bool, new Boolean("false"));

+        

+        upb = (Integer) props.get("upb");

+        ups = (Integer) props.get("ups");

+        upi = (Integer) props.get("upi");

+        upl = (Integer) props.get("upl");

+        upd = (Integer) props.get("upd");

+        upf = (Integer) props.get("upf");

+        upc = (Integer) props.get("upc");

+        upbool = (Integer) props.get("upbool");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationPrimitiveArrays() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+

+    public void testConfigurationPrimitiveArraysString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        byte[] b = (byte[]) props.get("bs");

+        short[] s = (short[]) props.get("ss");

+        int[] i = (int[]) props.get("is");

+        long[] l = (long[]) props.get("ls");

+        double[] d = (double[]) props.get("ds");

+        float[] f = (float[]) props.get("fs");

+        char[] c = (char[]) props.get("cs");

+        boolean[] bool = (boolean[]) props.get("bools");

+                

+        assertEquals("Check b 0", b[0], 1);

+        assertEquals("Check b 1", b[1], 2);

+        assertEquals("Check b 2", b[2], 3);

+        assertEquals("Check s 0", s[0], 1);

+        assertEquals("Check s 1", s[1], 2);

+        assertEquals("Check s 2", s[2], 3);

+        assertEquals("Check i 0", i[0], 1);

+        assertEquals("Check i 1", i[1], 2);

+        assertEquals("Check i 2", i[2], 3);

+        assertEquals("Check l 0", l[0], 1);

+        assertEquals("Check l 1", l[1], 2);

+        assertEquals("Check l 2", l[2], 3);

+        assertEquals("Check d 0", d[0], 1);

+        assertEquals("Check d 1", d[1], 2);

+        assertEquals("Check d 2", d[2], 3);

+        assertEquals("Check f 0", f[0], 1);

+        assertEquals("Check f 1", f[1], 2);

+        assertEquals("Check f 2", f[2], 3);

+        assertEquals("Check c 0", c[0], 'a');

+        assertEquals("Check c 1", c[1], 'b');

+        assertEquals("Check c 2", c[2], 'c');

+        assertTrue("Check bool 0", bool[0]);

+        assertTrue("Check bool 1", bool[0]);

+        assertTrue("Check bool 2", bool[0]);

+        

+        Integer upb = (Integer) props.get("upbs");

+        Integer ups = (Integer) props.get("upss");

+        Integer upi = (Integer) props.get("upis");

+        Integer upl = (Integer) props.get("upls");

+        Integer upd = (Integer) props.get("upds");

+        Integer upf = (Integer) props.get("upfs");

+        Integer upc = (Integer) props.get("upcs");

+        Integer upbool = (Integer) props.get("upbools");

+        

+        assertEquals("Check upb", upb, new Integer(1));

+        assertEquals("Check ups", ups, new Integer(1));

+        assertEquals("Check upi", upi, new Integer(1));

+        assertEquals("Check upl", upl, new Integer(1));

+        assertEquals("Check upd", upd, new Integer(1));

+        assertEquals("Check upf", upf, new Integer(1));

+        assertEquals("Check upc", upc, new Integer(1));

+        assertEquals("Check upbool", upbool, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        b = (byte[]) props.get("bs");

+        s = (short[]) props.get("ss");

+        i = (int[]) props.get("is");

+        l = (long[]) props.get("ls");

+        d = (double[]) props.get("ds");

+        f = (float[]) props.get("fs");

+        c = (char[]) props.get("cs");

+        bool = (boolean[]) props.get("bools");

+        

+        assertEquals("2) Check b 0", b[0], 3);

+        assertEquals("2) Check b 1", b[1], 2);

+        assertEquals("2) Check b 2", b[2], 1);

+        assertEquals("2) Check s 0", s[0], 3);

+        assertEquals("2) Check s 1", s[1], 2);

+        assertEquals("2) Check s 2", s[2], 1);

+        assertEquals("2) Check i 0", i[0], 3);

+        assertEquals("2) Check i 1", i[1], 2);

+        assertEquals("2) Check i 2", i[2], 1);

+        assertEquals("2) Check l 0", l[0], 3);

+        assertEquals("2) Check l 1", l[1], 2);

+        assertEquals("2) Check l 2", l[2], 1);

+        assertEquals("2) Check d 0", d[0], 3);

+        assertEquals("2) Check d 1", d[1], 2);

+        assertEquals("2) Check d 2", d[2], 1);

+        assertEquals("2) Check f 0", f[0], 3);

+        assertEquals("2) Check f 1", f[1], 2);

+        assertEquals("2) Check f 2", f[2], 1);

+        assertEquals("2) Check c 0", c[0], 'c');

+        assertEquals("2) Check c 1", c[1], 'b');

+        assertEquals("2) Check c 2", c[2], 'a');

+        assertFalse("2) Check bool 0", bool[0]);

+        assertFalse("2) Check bool 1", bool[0]);

+        assertFalse("2) Check bool 2", bool[0]);

+        

+        upb = (Integer) props.get("upbs");

+        ups = (Integer) props.get("upss");

+        upi = (Integer) props.get("upis");

+        upl = (Integer) props.get("upls");

+        upd = (Integer) props.get("upds");

+        upf = (Integer) props.get("upfs");

+        upc = (Integer) props.get("upcs");

+        upbool = (Integer) props.get("upbools");

+        

+        assertEquals("2) Check upb", upb, new Integer(2));

+        assertEquals("2) Check ups", ups, new Integer(2));

+        assertEquals("2) Check upi", upi, new Integer(2));

+        assertEquals("2) Check upl", upl, new Integer(2));

+        assertEquals("2) Check upd", upd, new Integer(2));

+        assertEquals("2) Check upf", upf, new Integer(2));

+        assertEquals("2) Check upc", upc, new Integer(2));

+        assertEquals("2) Check upbool", upbool, new Integer(2));

+        

+    }

+    

+    public void testConfigurationObj() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigure();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+

+    public void testConfigurationObjString() {

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        CheckService check = (CheckService) context.getService(ref);

+        Properties props = check.getProps();

+        

+        String s = (String) props.get("string");

+        String[] ss = (String[]) props.get("strings");

+                

+        assertEquals("Check string", s, "foo");

+        assertEquals("Check strings 0", ss[0], "foo");

+        assertEquals("Check strings 1", ss[1], "bar");

+        assertEquals("Check strings 2", ss[2], "baz");

+        

+        Integer upString = (Integer) props.get("upstring");

+        Integer upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("Check upString", upString, new Integer(1));

+        assertEquals("Check upStrings", upStrings, new Integer(1));

+        

+        reconfigureString();

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Test check service availability", ref);

+        check = (CheckService) context.getService(ref);

+        props = check.getProps();

+        

+        s = (String) props.get("string");

+        ss = (String[]) props.get("strings");

+                

+        assertEquals("2) Check string", s, "bar");

+        assertEquals("2) Check strings 0", ss[0], "baz");

+        assertEquals("2) Check strings 1", ss[1], "bar");

+        assertEquals("2) Check strings 2", ss[2], "foo");

+        

+        upString = (Integer) props.get("upstring");

+        upStrings = (Integer) props.get("upstrings");

+        

+        assertEquals("2) Check upString", upString, new Integer(2));

+        assertEquals("2) Check upStrings", upStrings, new Integer(2));

+    }

+    

+    private void reconfigure() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", new Byte("2"));

+        props2.put("s", new Short("2"));

+        props2.put("i", new Integer("2"));

+        props2.put("l", new Long("2"));

+        props2.put("d", new Double("2"));

+        props2.put("f", new Float("2"));

+        props2.put("c", new Character('b'));

+        props2.put("bool", new Boolean(false));

+        props2.put("bs", new byte[]{(byte)3,(byte)2,(byte)1});

+        props2.put("ss", new short[]{(short)3,(short)2,(short)1});

+        props2.put("is", new int[]{3,2,1});

+        props2.put("ls", new long[]{3,2,1});

+        props2.put("ds", new double[]{3,2,1});

+        props2.put("fs", new float[]{3,2,1});

+        props2.put("cs", new char[]{'c','b','a'});

+        props2.put("bools", new boolean[]{false,false,false});

+        props2.put("string", "bar");

+        props2.put("strings", new String[]{"baz", "bar", "foo"});

+        

+        instance.reconfigure(props2);

+    }

+    

+    private void reconfigureString() {

+        Properties props2 = new Properties();

+        props2.put("name", "under-test");

+        props2.put("b", "2");

+        props2.put("s", "2");

+        props2.put("i", "2");

+        props2.put("l", "2");

+        props2.put("d", "2");

+        props2.put("f", "2");

+        props2.put("c", "b");

+        props2.put("bool", "false");

+        props2.put("bs", "{3, 2,1}");

+        props2.put("ss", "{3, 2,1}");

+        props2.put("is", "{3, 2,1}");

+        props2.put("ls", "{3, 2,1}");

+        props2.put("ds", "{3, 2,1}");

+        props2.put("fs", "{3, 2,1}");

+        props2.put("cs", "{c, b , a}");

+        props2.put("bools", "{false,false,false}");

+        props2.put("string", "bar");

+        props2.put("strings", "{baz, bar, foo}");

+        

+        instance.reconfigure(props2);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/ImmediateLifeCycleControllerTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/ImmediateLifeCycleControllerTest.java
new file mode 100644
index 0000000..c5f5e20
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/ImmediateLifeCycleControllerTest.java
@@ -0,0 +1,115 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.controller;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ImmediateLifeCycleControllerTest extends OSGiTestCase {

+    

+    private ComponentInstance under;

+    private Factory factory;

+    

+    public void setUp() {

+        factory = Utils.getFactoryByName(context, "lcTest2");

+    }

+    

+    public void testOne() {

+        Properties props = new Properties();

+        props.put("conf", "foo");

+        props.put("name", "under");

+        under = Utils.getComponentInstance(context, "lcTest2", props);

+        

+        // The conf is correct, the PS must be provided

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -1", ref);

+        CheckService cs = (CheckService) context.getService(ref);

+        assertTrue("Check state 1", cs.check());

+        context.ungetService(ref);

+        cs = null;

+        

+        // Reconfigure the instance with a bad configuration

+        props.put("conf", "bar"); // Bar is a bad conf

+        try {

+            factory.reconfigure(props);

+        } catch(Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable : " + props);

+        }

+        

+        // The instance should now be invalid 

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNull("Check service availability -2", ref);

+        

+        // Reconfigure the instance with a valid configuration

+        props.put("conf", "foo"); // Bar is a bad conf

+        try {

+            factory.reconfigure(props);

+        } catch(Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable (2) : " + props);

+        }

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -3", ref);

+        cs = (CheckService) context.getService(ref);

+        assertTrue("Check state 2", cs.check());

+        context.ungetService(ref);

+        cs = null;

+        

+        under.dispose();

+    }

+    

+    public void testTwo() {        

+        Properties props = new Properties();

+        props.put("conf", "bar");

+        props.put("name", "under");

+        under = Utils.getComponentInstance(context, "lcTest2", props);    

+        

+        assertEquals("check under state", under.getState(), ComponentInstance.INVALID);

+        

+        // The conf is incorrect, the PS must not be provided

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNull("Check service availability -1", ref);

+        

+        // Reconfigure the instance with a correct configuration

+        props.put("conf", "foo");

+        try {

+            factory.reconfigure(props);

+        } catch(Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable : " + props);

+        }

+        

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -2", ref);

+        CheckService cs = (CheckService) context.getService(ref);

+        assertTrue("Check state ", cs.check());

+        context.ungetService(ref);

+        cs = null;

+        

+        under.dispose();

+    }

+    

+    

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTest.java
new file mode 100644
index 0000000..d86b997
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTest.java
@@ -0,0 +1,134 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.controller;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * @author clement

+ *

+ */

+public class LifeCycleControllerTest extends OSGiTestCase {

+

+    private ComponentInstance under;

+

+    private Factory factory;

+

+    public void setUp() {

+        factory = Utils.getFactoryByName(context, "lcTest");

+    }

+

+    public void testOne() {

+        Properties props = new Properties();

+        props.put("conf", "foo");

+        props.put("name", "under");

+        under = Utils.getComponentInstance(context, "lcTest", props);

+

+        // The conf is correct, the PS must be provided

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -1", ref);

+        CheckService cs = (CheckService) context.getService(ref);

+        assertTrue("Check state 1", cs.check());

+        context.ungetService(ref);

+        cs = null;

+

+        // Reconfigure the instance with a bad configuration

+        props.put("conf", "bar"); // Bar is a bad conf

+        try {

+            factory.reconfigure(props);

+        } catch (Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable : " + props);

+        }

+

+        // The instance should now be invalid 

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNull("Check service availability -2", ref);

+

+        // Reconfigure the instance with a valid configuration

+        props.put("conf", "foo"); // Bar is a bad conf

+        try {

+            factory.reconfigure(props);

+        } catch (Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable (2) : " + props);

+        }

+

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -3", ref);

+        cs = (CheckService) context.getService(ref);

+        assertTrue("Check state 2", cs.check());

+        context.ungetService(ref);

+        cs = null;

+

+        under.dispose();

+    }

+

+    /**

+     * This test must be removed as it is not compliant with OSGi. It unregisters a service during the creation of the 

+     * service instance, so the returned object is null. 

+     */

+    public void notestTwo() {

+        Properties props = new Properties();

+        props.put("conf", "bar");

+        props.put("name", "under");

+        under = Utils.getComponentInstance(context, "lcTest", props);

+

+        // The conf is incorrect, but the test can appears only when the object is created : the PS must be provided

+        ServiceReference ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -1", ref);

+

+        System.out.println("CS received : " + context.getService(ref));

+        CheckService cs = (CheckService) context.getService(ref);

+        assertNotNull("Assert CS not null", cs);

+        try {

+            assertFalse("Check state (false)", cs.check());

+        } catch (Throwable e) {

+            e.printStackTrace();

+            fail(e.getMessage());

+        }

+

+        // As soon as the instance is created, the service has to disappear :

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNull("Check service availability -2", ref);

+

+        // Reconfigure the instance with a correct configuration

+        props.put("conf", "foo");

+        try {

+            factory.reconfigure(props);

+        } catch (Exception e) {

+            fail("The reconfiguration is not unacceptable and seems unacceptable : " + props);

+        }

+

+        ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "under");

+        assertNotNull("Check service availability -3", ref);

+        cs = (CheckService) context.getService(ref);

+        assertTrue("Check state ", cs.check());

+        context.ungetService(ref);

+        cs = null;

+

+        under.dispose();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTestSuite.java
new file mode 100644
index 0000000..423088f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/controller/LifeCycleControllerTestSuite.java
@@ -0,0 +1,36 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.controller;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class LifeCycleControllerTestSuite {

+

+

+    public static Test suite(BundleContext bc) {

+        OSGiTestSuite ots = new OSGiTestSuite("Lifecycle Controller Test Suite", bc);

+        ots.addTestSuite( LifeCycleControllerTest.class);

+        ots.addTestSuite( ImmediateLifeCycleControllerTest.class);

+        return ots;

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/ComponentDesc.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/ComponentDesc.java
new file mode 100644
index 0000000..df3d25a
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/ComponentDesc.java
@@ -0,0 +1,336 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.core;

+

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;

+import org.apache.felix.ipojo.architecture.PropertyDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ComponentDesc extends OSGiTestCase {

+	

+	ServiceReference sr_fooProvider1;

+	ServiceReference sr_fooProvider2;

+	ServiceReference sr_fooProviderDyn2;

+	ServiceReference sr_fooProvider3;

+	ServiceReference sr_foobarProvider;

+//	ServiceReference sr_simple;

+//	ServiceReference sr_optional;

+//	ServiceReference sr_multiple;

+//	ServiceReference sr_multiple_optional;

+	

+	Factory fooProvider1;

+	Factory fooProvider2;

+	Factory fooProviderDyn2;

+	Factory fooProvider3;

+	Factory foobarProvider;

+//	Factory simple;

+//	Factory optional;

+//	Factory multiple;

+//	Factory multiple_optional;

+	

+	public void setUp() {

+		sr_fooProvider1 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-1");

+		sr_fooProvider2 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-2");

+		sr_fooProviderDyn2 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-Dyn2");

+		sr_fooProvider3 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-3");

+		sr_foobarProvider = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooBarProviderType-1");

+//		sr_simple = Utils.getServiceReferenceByName(context, Factory.class.getName(), "SimpleCheckServiceProvider");

+//		sr_optional = Utils.getServiceReferenceByName(context, Factory.class.getName(), "SimpleOptionalCheckServiceProvider");

+//		sr_multiple = Utils.getServiceReferenceByName(context, Factory.class.getName(), "SimpleMultipleCheckServiceProvider");

+//		sr_multiple_optional = Utils.getServiceReferenceByName(context, Factory.class.getName(), "SimpleOptionalMultipleCheckServiceProvider");

+		

+		fooProvider1 = (Factory) context.getService(sr_fooProvider1);

+		fooProvider2 = (Factory) context.getService(sr_fooProvider2);

+		fooProviderDyn2 = (Factory) context.getService(sr_fooProviderDyn2);

+		fooProvider3 = (Factory) context.getService(sr_fooProvider3);

+		foobarProvider = (Factory) context.getService(sr_foobarProvider);

+//		simple = (Factory) context.getService(sr_simple);

+//		optional = (Factory) context.getService(sr_optional);

+//		multiple = (Factory) context.getService(sr_multiple);

+//		multiple_optional = (Factory) context.getService(sr_multiple_optional);

+		

+	}

+	

+	public void tearDown() {

+		fooProvider1 = null;

+		fooProvider2 = null;

+		fooProviderDyn2 = null;

+		fooProvider3 = null;

+		foobarProvider = null;

+//		simple = null;

+//		multiple = null;

+//		optional = null;

+//		multiple_optional = null;

+		

+		context.ungetService(sr_fooProvider1);

+		context.ungetService(sr_fooProvider2);

+		context.ungetService(sr_fooProviderDyn2);

+		context.ungetService(sr_fooProvider3);

+		context.ungetService(sr_foobarProvider);

+//		context.ungetService(sr_simple);

+//		context.ungetService(sr_optional);

+//		context.ungetService(sr_multiple);

+//		context.ungetService(sr_multiple_optional);

+	}

+	

+	public void testFooProvider1() {

+		// Test SR properties

+//		String impl = (String) sr_fooProvider1.getProperty("component.class");

+//		assertEquals("Check component.class", impl, "org.apache.felix.ipojo.test.scenarios.component.FooProviderType1");

+		

+		String[] specs = (String[]) sr_fooProvider1.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check component.providedServiceSpecifications length", specs.length, 1);

+		assertEquals("Check component.providedServiceSpecifications", FooService.class.getName(), specs[0]);

+		

+		PropertyDescription[] pd = (PropertyDescription[]) sr_fooProvider1.getProperty("component.properties");

+		assertEquals("Check component.properties length", pd.length, 0);

+		

+		// Test factory

+		assertEquals("Check factory name", fooProvider1.getName(), "FooProviderType-1");

+		Element cd = fooProvider1.getDescription();

+		

+//		assertEquals("Check implementation class ", cd.getAttribute("implementation-class"), impl);

+		

+		Element[] specs2 = cd.getElements("provides");

+		assertEquals("Check specs length", specs2.length, 1);

+		assertEquals("Check specs", FooService.class.getName(), specs2[0].getAttribute("specification"));

+		

+		Element[] pd2 = cd.getElements("property");

+		assertNull("Check props null", pd2);

+		

+		// Check Description equality

+		ComponentTypeDescription desc = (ComponentTypeDescription) sr_fooProvider1.getProperty("component.description");

+		assertNotNull("check description equality", desc);

+	}

+	

+	public void testFooProvider2() {

+		// Test SR properties

+//		String impl = (String) sr_fooProvider2.getProperty("component.class");

+//		assertEquals("Check component.class", impl, "org.apache.felix.ipojo.test.scenarios.component.FooProviderType1");

+		

+		String[] specs = (String[]) sr_fooProvider2.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check component.providedServiceSpecifications length", specs.length, 1);

+		assertEquals("Check component.providedServiceSpecifications", FooService.class.getName(), specs[0]);

+		

+		PropertyDescription[] pd = (PropertyDescription[]) sr_fooProvider2.getProperty("component.properties");

+		assertEquals("Check component.properties length", pd.length, 5);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "int", pd[0].getName());

+		assertEquals("Check component.properties type [" + 0 + "]", "int", pd[0].getType());

+		assertEquals("Check component.properties value [" + 0 + "]", "2", pd[0].getValue());

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "long", pd[1].getName());

+		assertEquals("Check component.properties type [" + 1 + "]", "long", pd[1].getType());

+		assertEquals("Check component.properties value [" + 1 + "]", "40", pd[1].getValue());

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "string", pd[2].getName());

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd[2].getType());

+		assertEquals("Check component.properties value [" + 2 + "]", "foo", pd[2].getValue());

+		

+		assertEquals("Check component.properties name [" + 3 + "]", "strAProp", pd[3].getName());

+		assertEquals("Check component.properties type [" + 3 + "]", "java.lang.String[]", pd[3].getType());

+		

+		assertEquals("Check component.properties name [" + 4 + "]", "intAProp", pd[4].getName());

+		assertEquals("Check component.properties type [" + 4 + "]", "int[]", pd[4].getType());

+		

+		// Test factory

+		assertEquals("Check factory name", fooProvider2.getName(), "FooProviderType-2");

+		Element cd = fooProvider2.getDescription();

+        

+//        assertEquals("Check implementation class ", cd.getAttribute("implementation-class"), impl);

+		

+        Element[] specs2 = cd.getElements("provides");

+        assertEquals("Check specs length", specs2.length, 1);

+        assertEquals("Check specs", FooService.class.getName(), specs2[0].getAttribute("specification"));

+		

+        Element[] pd2 = cd.getElements("property");

+		assertEquals("Check props length", pd2.length, 5);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "int", pd2[0].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 0 + "]", "int", pd2[0].getAttribute("type"));

+		assertEquals("Check component.properties value [" + 0 + "]", "2", pd2[0].getAttribute("value"));

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "long", pd2[1].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 1 + "]", "long", pd2[1].getAttribute("type"));

+		assertEquals("Check component.properties value [" + 1 + "]", "40", pd2[1].getAttribute("value"));

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "string", pd2[2].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd2[2].getAttribute("type"));

+		assertEquals("Check component.properties value [" + 2 + "]", "foo", pd2[2].getAttribute("value"));

+		

+		assertEquals("Check component.properties name [" + 3 + "]", "strAProp", pd2[3].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 3 + "]", "java.lang.String[]", pd2[3].getAttribute("type"));

+		

+		assertEquals("Check component.properties name [" + 4 + "]", "intAProp", pd2[4].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 4 + "]", "int[]", pd2[4].getAttribute("type"));

+		

+		// Check Description equality

+		ComponentTypeDescription desc = (ComponentTypeDescription) sr_fooProvider2.getProperty("component.description");

+        assertNotNull("check description equality", desc);

+	}

+	

+	public void testFooProviderDyn2() {

+		// Test SR properties

+//		String impl = (String) sr_fooProviderDyn2.getProperty("component.class");

+//		assertEquals("Check component.class", impl, "org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn2");

+		

+		String[] specs = (String[]) sr_fooProviderDyn2.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check component.providedServiceSpecifications length", specs.length, 1);

+		assertEquals("Check component.providedServiceSpecifications", FooService.class.getName(), specs[0]);

+		

+		PropertyDescription[] pd = (PropertyDescription[]) sr_fooProviderDyn2.getProperty("component.properties");

+		assertEquals("Check component.properties length", pd.length, 5);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "int", pd[0].getName());

+		assertEquals("Check component.properties type [" + 0 + "]", "int", pd[0].getType());

+		assertEquals("Check component.properties value [" + 0 + "]", "4", pd[0].getValue());

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "boolean", pd[1].getName());

+		assertEquals("Check component.properties type [" + 1 + "]", "boolean", pd[1].getType());

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "string", pd[2].getName());

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd[2].getType());

+		

+		assertEquals("Check component.properties name [" + 3 + "]", "strAProp", pd[3].getName());

+		assertEquals("Check component.properties type [" + 3 + "]", "java.lang.String[]", pd[3].getType());

+		

+		assertEquals("Check component.properties name [" + 4 + "]", "intAProp", pd[4].getName());

+		assertEquals("Check component.properties type [" + 4 + "]", "int[]", pd[4].getType());

+		

+		// Test factory

+		assertEquals("Check factory name", fooProviderDyn2.getName(), "FooProviderType-Dyn2");

+		Element cd = fooProviderDyn2.getDescription();

+		

+//        assertEquals("Check implementation class ", cd.getAttribute("implementation-class"), impl);

+        

+        Element[] specs2 = cd.getElements("provides");

+        assertEquals("Check specs length", specs2.length, 1);

+        assertEquals("Check specs", FooService.class.getName(), specs2[0].getAttribute("specification"));

+        

+        Element[] pd2 = cd.getElements("property");

+        assertEquals("Check props length", pd2.length, 5);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "int", pd2[0].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 0 + "]", "int", pd2[0].getAttribute("type"));

+		assertEquals("Check component.properties value [" + 0 + "]", "4", pd2[0].getAttribute("value"));

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "boolean", pd2[1].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 1 + "]", "boolean", pd2[1].getAttribute("type"));

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "string", pd2[2].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd2[2].getAttribute("type"));

+		

+		assertEquals("Check component.properties name [" + 3 + "]", "strAProp", pd2[3].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 3 + "]", "java.lang.String[]", pd2[3].getAttribute("type"));

+		

+		assertEquals("Check component.properties name [" + 4 + "]", "intAProp", pd2[4].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 4 + "]", "int[]", pd2[4].getAttribute("type"));

+		

+		// Check Description equality

+		ComponentTypeDescription desc = (ComponentTypeDescription) sr_fooProviderDyn2.getProperty("component.description");

+		assertNotNull("check description equality", desc);

+	}

+	

+	public void testFooProvider3() {

+		// Test SR properties

+//		String impl = (String) sr_fooProvider3.getProperty("component.class");

+//		assertEquals("Check component.class", impl, "org.apache.felix.ipojo.test.scenarios.component.FooProviderType1");

+		

+		String[] specs = (String[]) sr_fooProvider3.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check component.providedServiceSpecifications length", specs.length, 1);

+		assertEquals("Check component.providedServiceSpecifications", FooService.class.getName(), specs[0]);

+		

+		PropertyDescription[] pd = (PropertyDescription[]) sr_fooProvider3.getProperty("component.properties");

+		assertEquals("Check component.properties length (" + pd.length +")", pd.length, 3);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "foo", pd[0].getName());

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "bar", pd[1].getName());

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "baz", pd[2].getName());

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd[2].getType());

+		

+		// Test factory

+		assertEquals("Check factory name", fooProvider3.getName(), "FooProviderType-3");

+		Element cd = fooProvider3.getDescription();

+        

+//		assertEquals("Check implementation class ", cd.getAttribute("implementation-class"), impl);

+        

+        Element[] specs2 = cd.getElements("provides");

+        assertEquals("Check specs length", specs2.length, 1);

+        assertEquals("Check specs", FooService.class.getName(), specs2[0].getAttribute("specification"));

+        

+        Element[] pd2 = cd.getElements("property");

+        assertEquals("Check props length", pd2.length, 3);

+		

+		assertEquals("Check component.properties name [" + 0 + "]", "foo", pd2[0].getAttribute("name"));

+		

+		assertEquals("Check component.properties name [" + 1 + "]", "bar", pd2[1].getAttribute("name"));

+		

+		assertEquals("Check component.properties name [" + 2 + "]", "baz", pd2[2].getAttribute("name"));

+		assertEquals("Check component.properties type [" + 2 + "]", "java.lang.String", pd2[2].getAttribute("type"));

+		

+		// Check Description equality

+		ComponentTypeDescription desc = (ComponentTypeDescription) sr_fooProvider3.getProperty("component.description");

+		assertNotNull("check description equality", desc);

+	}

+	

+	public void testFooBar() {

+		//	Test SR properties

+//		String impl = (String) sr_foobarProvider.getProperty("component.class");

+//		assertEquals("Check component.class", impl, "org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1");

+		

+		String[] specs = (String[]) sr_foobarProvider.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check component.providedServiceSpecifications length", specs.length, 2);

+		assertEquals("Check component.providedServiceSpecifications 1", FooService.class.getName(), specs[1]);

+		assertEquals("Check component.providedServiceSpecifications 2", BarService.class.getName(), specs[0]);

+		

+		PropertyDescription[] pd = (PropertyDescription[]) sr_foobarProvider.getProperty("component.properties");

+		assertEquals("Check component.properties length", pd.length, 0);

+		

+		// Test factory

+		assertEquals("Check factory name", foobarProvider.getName(), "FooBarProviderType-1");

+		Element cd = foobarProvider.getDescription();

+		

+//        assertEquals("Check implementation class ", cd.getAttribute("implementation-class"), impl);

+		

+        Element[] specs2 = cd.getElements("provides");

+        assertEquals("Check specs length", specs2.length, 2);

+        assertEquals("Check specs", FooService.class.getName(), specs2[1].getAttribute("specification"));

+        assertEquals("Check specs", BarService.class.getName(), specs2[0].getAttribute("specification"));

+        

+        Element[] pd2 = cd.getElements("property");

+        assertNull("Check props null", pd2);

+		

+		// Check Description equality

+        ComponentTypeDescription desc = (ComponentTypeDescription) sr_foobarProvider.getProperty("component.description");

+		assertNotNull("check description equality", desc);

+

+	}

+	

+	

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/CoreTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/CoreTestSuite.java
new file mode 100644
index 0000000..bc87ae4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/CoreTestSuite.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.core;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class CoreTestSuite extends TestSuite {

+	

+	

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Contre Test Suite", bc);

+		ots.addTestSuite(POJOCreation.class);

+		ots.addTestSuite(ComponentDesc.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/POJOCreation.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/POJOCreation.java
new file mode 100644
index 0000000..7c76bbf
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/core/POJOCreation.java
@@ -0,0 +1,264 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.core;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.component.FooProviderType1;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class POJOCreation extends OSGiTestCase {

+	

+	private ComponentInstance ci_lazzy;

+	private ComponentInstance ci_immediate;

+	private ComponentInstance ci_immediate_singleton;

+	

+	private Architecture lazzyArch;

+	private Architecture immeArch;

+	private Architecture immeArchSing;

+	

+	private ServiceReference lazzyRef;

+	private ServiceReference immRef;

+	private ServiceReference immRefSing;

+    private ComponentInstance ci_lazzy_sing;

+    private ComponentInstance ci_lazzy_sev;

+    private ServiceReference lazzyRefSing;

+    private ServiceReference lazzyRefSev;

+    private Architecture lazzyArchSing;

+    private Architecture lazzyArchSev;

+    private ComponentInstance ci_lazzy_singM;

+    private ComponentInstance ci_lazzy_sevM;

+    private ServiceReference lazzyRefSingM;

+    private ServiceReference lazzyRefSevM;

+    private Architecture lazzyArchSingM;

+    private Architecture lazzyArchSevM;

+	

+	public void setUp() {

+		String factName = "FooProviderType-1";

+		String compName = "FooProvider-1";

+		Properties p = new Properties();

+		p.put("name", compName);

+		ci_lazzy = Utils.getComponentInstance(context, factName ,p);

+		

+		String factName2 = "ImmediateFooProviderType";

+		String compName2 = "FooProvider-2";

+		Properties p2 = new Properties();

+		p2.put("name", compName2);

+		ci_immediate = Utils.getComponentInstance(context, factName2, p2);

+		

+		String factName3 = "ImmediateFooProviderTypeSingleton";

+        String compName3 = "FooProvider-3";

+        Properties p3 = new Properties();

+        p3.put("name", compName3);

+        ci_immediate_singleton = Utils.getComponentInstance(context, factName3, p3);

+        

+        String factName4 = "FooProviderType-1-Sing";

+        String compName4 = "FooProvider-1-Sing";

+        Properties p4 = new Properties();

+        p4.put("name", compName4);

+        ci_lazzy_sing = Utils.getComponentInstance(context, factName4 ,p4);

+        

+        String factName5 = "FooProviderType-1-Sev";

+        String compName5 = "FooProvider-1-Sev";

+        Properties p5 = new Properties();

+        p5.put("name", compName5);

+        ci_lazzy_sev = Utils.getComponentInstance(context, factName5 ,p5);

+        

+        String factName6 = "FooProviderType-1-SingM";

+        String compName6 = "FooProvider-1-SingM";

+        Properties p6 = new Properties();

+        p6.put("name", compName6);

+        ci_lazzy_singM = Utils.getComponentInstance(context, factName6 ,p6);

+        

+        String factName7 = "FooProviderType-1-SevM";

+        String compName7 = "FooProvider-1-SevM";

+        Properties p7 = new Properties();

+        p7.put("name", compName7);

+        ci_lazzy_sevM = Utils.getComponentInstance(context, factName7 ,p7);

+		

+		lazzyRef = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName+")");

+		immRef =   Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName2+")");

+		immRefSing = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName3+")");

+		lazzyRefSing = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName4+")");

+		lazzyRefSev = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName5+")");

+		lazzyRefSingM = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName6+")");

+		lazzyRefSevM = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName7+")");

+		

+		lazzyArch = (Architecture) context.getService(lazzyRef);

+		immeArch = (Architecture) context.getService(immRef);

+		immeArchSing = (Architecture) context.getService(immRefSing);

+		lazzyArchSing = (Architecture) context.getService(lazzyRefSing);

+		lazzyArchSev = (Architecture) context.getService(lazzyRefSev);

+	    lazzyArchSingM = (Architecture) context.getService(lazzyRefSingM);

+	    lazzyArchSevM = (Architecture) context.getService(lazzyRefSevM);

+	}

+	

+	public void tearDown() {

+		context.ungetService(lazzyRef);

+		context.ungetService(immRef);

+		context.ungetService(immRefSing);

+		context.ungetService(lazzyRefSing);

+		context.ungetService(lazzyRefSev);

+		context.ungetService(lazzyRefSingM);

+        context.ungetService(lazzyRefSevM);

+		lazzyArch = null;

+		immeArch = null;

+		immeArchSing = null;

+		lazzyArchSing = null;

+		lazzyArchSev = null;

+		lazzyArchSingM = null;

+        lazzyArchSevM = null;

+		ci_lazzy.dispose();

+		ci_immediate.dispose();

+		ci_immediate_singleton.dispose();

+		ci_lazzy_sing.dispose();

+		ci_lazzy_sev.dispose();

+		ci_lazzy_singM.dispose();

+        ci_lazzy_sevM.dispose();

+	}

+	

+	public void testLazyCreation() {

+		assertEquals("Check that no objects are created ", 0, lazzyArch.getInstanceDescription().getCreatedObjects().length);

+		ServiceReference[] refs = null;

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy.getInstanceName()+")");

+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }

+		assertNotNull("Check that a FooService from " + ci_lazzy.getInstanceName() + " is available",refs);

+		FooService fs = (FooService) context.getService(refs[0]);

+		assertTrue("Check the FooService invocation", fs.foo());

+		assertEquals("Check the creation of 1 object",1, lazzyArch.getInstanceDescription().getCreatedObjects().length);

+		context.ungetService(refs[0]);

+	}

+	

+	public void testLazyCreationSingleton() {

+        assertEquals("Check that no objects are created ", 0, lazzyArchSing.getInstanceDescription().getCreatedObjects().length);

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy_sing.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy_sing.getInstanceName() + " is available",refs);

+        FooService fs = (FooService) context.getService(refs[0]);

+        assertTrue("Check the FooService invocation", fs.foo());

+        assertEquals("Check the creation of 1 object",1, lazzyArchSing.getInstanceDescription().getCreatedObjects().length);

+        context.ungetService(refs[0]);

+    }

+	

+	public void testLazyCreationSeveral() {

+        assertEquals("Check that no objects are created ", 0, lazzyArchSev.getInstanceDescription().getCreatedObjects().length);

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy_sev.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy_sev.getInstanceName() + " is available",refs);

+        FooService fs = (FooService) context.getService(refs[0]);

+        FooService fs2 = (FooService) context.getService(refs[0]);

+        assertTrue("Check the FooService invocation", fs.foo());

+        assertTrue("Check the FooService invocation-2", fs2.foo());

+        assertEquals("Check the creation of 1 object",1, lazzyArchSev.getInstanceDescription().getCreatedObjects().length);

+        context.ungetService(refs[0]);

+    }

+	

+	public void testImmediateCreation() {

+		assertEquals("Check that one object is created ", 1, immeArch.getInstanceDescription().getCreatedObjects().length);

+		ServiceReference[] refs = null;

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_immediate.getInstanceName()+")");

+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }

+		assertNotNull("Check that a FooService from " + ci_immediate.getInstanceName() + " is available",refs);

+		FooService fs = (FooService) context.getService(refs[0]);

+		assertTrue("Check the FooService invocation", fs.foo());

+		assertEquals("Check the creation of 1 object", 1, immeArch.getInstanceDescription().getCreatedObjects().length);

+		context.ungetService(refs[0]);

+	}

+    

+    public void testBundleContext() {

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy.getInstanceName() + " is available",refs);

+        FooService fs = (FooService) context.getService(refs[0]);

+        Properties p = fs.fooProps();

+        assertNotNull("Check the bundle context", p.get("context"));

+        assertEquals("Check the creation of 1 object",1, lazzyArch.getInstanceDescription().getCreatedObjects().length);

+        context.ungetService(refs[0]);

+    }

+

+    public void testImmediateSingletonCreation() {

+    	assertEquals("Check that one object is created ", 1, immeArchSing.getInstanceDescription().getCreatedObjects().length);

+    	ServiceReference[] refs = null;

+    	try {

+    		refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_immediate_singleton.getInstanceName()+")");

+    	} catch (InvalidSyntaxException e) { e.printStackTrace(); }

+    	assertNotNull("Check that a FooService from " + ci_immediate_singleton.getInstanceName() + " is available",refs);

+    	FooService fs = (FooService) context.getService(refs[0]);

+    	assertTrue("Check the FooService invocation", fs.foo());

+    	assertEquals("Check the creation of 1 object", 1, immeArchSing.getInstanceDescription().getCreatedObjects().length);

+    	context.ungetService(refs[0]);

+    }

+

+    public void testLazyCreationSingletonM() {

+        assertEquals("Check that no objects are created ", 0, lazzyArchSingM.getInstanceDescription().getCreatedObjects().length);

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy_singM.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy_singM.getInstanceName() + " is available",refs);

+        FooService fs = (FooService) context.getService(refs[0]);

+        FooService fs2 = (FooService) context.getService(refs[0]);

+        assertTrue("Check the FooService invocation", fs.foo());

+        assertTrue("Check the FooService invocation", fs2.foo());

+        assertEquals("Check the creation of 1 object",1, lazzyArchSingM.getInstanceDescription().getCreatedObjects().length);

+        context.ungetService(refs[0]);

+    }

+

+    public void testLazyCreationSeveralM() {

+        assertEquals("Check that no objects are created ", 0, lazzyArchSevM.getInstanceDescription().getCreatedObjects().length);

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy_sevM.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy_sevM.getInstanceName() + " is available",refs);

+        FooService fs = (FooService) context.getService(refs[0]);

+        assertTrue("Check the FooService invocation", fs.foo());

+        assertEquals("Check the creation of 1 object",1, lazzyArchSevM.getInstanceDescription().getCreatedObjects().length);

+        FooService fs2 = (FooService) context.getService(refs[0]);

+        assertTrue("Check the FooService invocation-2", fs2.foo());

+        // Only one object as the getService method is called only once (service factory) despite the policy="method".

+        assertEquals("Check the creation of 1 object",1, lazzyArchSevM.getInstanceDescription().getCreatedObjects().length);

+        context.ungetService(refs[0]);

+    }

+    

+    public void testCustomConstuctor() {

+        FooService fs = new FooProviderType1(0, "foo", context);

+        Properties props = fs.fooProps();

+        assertEquals("Check bar", 0, ((Integer) props.get("bar")).intValue());

+        assertEquals("Check foo", "foo", props.get("foo"));

+        assertEquals("Check context", context, props.get("context"));

+    }

+    

+    

+

+}
\ No newline at end of file
diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedMultipleDependencies.java
new file mode 100644
index 0000000..edc0b2f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedMultipleDependencies.java
@@ -0,0 +1,368 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleMultipleCheckServiceProvider").createComponentInstance(i1);

+			instance1.stop();

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidMultipleCheckServiceProvider").createComponentInstance(i2);

+			instance2.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectMultipleCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefMultipleCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+			

+	         Properties i5 = new Properties();

+	            i5.put("name", "Both");

+	            instance5 = Utils.getFactoryByName(context, "BothMultipleCheckServiceProvider").createComponentInstance(i5);

+	            instance5.stop();

+		

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+		} catch(Exception e) { fail(e.getMessage()); }

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimple() {

+		instance1.start();

+		

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0, 0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0, 0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance1.stop();

+	}

+	

+	public void testVoid() {

+		instance2.start();

+		

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0, 0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0, 0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+		instance2.stop();

+	}

+	

+	public void testObject() {

+		instance3.start();

+		

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0, 0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0, 0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0, 0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0, 0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		instance4.stop();

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        instance5.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 1", ((Integer)props.get("bothU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+        assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+        assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0, 0);

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 3", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 3", ((Integer)props.get("bothU")).intValue(), 1);

+        assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0, 0);

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        instance5.stop();

+        context.ungetService(cs_ref);

+    }

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalDependencies.java
new file mode 100644
index 0000000..763ebca
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalDependencies.java
@@ -0,0 +1,353 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance1, instance2, instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+

+            Properties i1 = new Properties();

+            i1.put("name", "Simple");

+            instance1 = Utils.getFactoryByName(context, "SimpleOptionalCheckServiceProvider").createComponentInstance(i1);

+            instance1.stop();

+

+            Properties i2 = new Properties();

+            i2.put("name", "Void");

+            instance2 = Utils.getFactoryByName(context, "VoidOptionalCheckServiceProvider").createComponentInstance(i2);

+            instance2.stop();

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "ObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+            instance3.stop();

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "RefOptionalCheckServiceProvider").createComponentInstance(i4);

+            instance4.stop();

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "BothOptionalCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+

+    }

+

+    public void tearDown() {

+        instance1.dispose();

+        instance2.dispose();

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance1 = null;

+        instance2 = null;

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testSimple() {

+        instance1.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 1", props.get("object"));

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation - 2", ((Boolean) props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 0);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 0);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 0.0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance1.stop();

+    }

+

+    public void testVoid() {

+        instance2.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 1", props.get("object"));

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 1);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 0);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 0);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 0.0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance2.stop();

+    }

+

+    public void testObject() {

+        instance3.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance3.stop();

+    }

+

+    public void testRef() {

+        instance4.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+    public void testBoth() {

+        instance5.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalMultipleDependencies.java
new file mode 100644
index 0000000..2546039
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedOptionalMultipleDependencies.java
@@ -0,0 +1,356 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedOptionalMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance1, instance2, instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {		

+		try {

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleOptionalMultipleCheckServiceProvider").createComponentInstance(i1);

+			instance1.stop();

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidOptionalMultipleCheckServiceProvider").createComponentInstance(i2);

+			instance2.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectOptionalMultipleCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefOptionalMultipleCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+		

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+		} catch(Exception e) { fail(e.getMessage()); }		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimple() {

+		instance1.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, it still one provider.

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 4", ((Boolean)props.get("result")).booleanValue()); // False, no more provider.

+		assertEquals("check void bind invocation - 4", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 4", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 4", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 4", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 4", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 4", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 4", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 4", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 4", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+		instance1.stop();

+	}

+	

+	public void testVoid() {

+		instance2.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 4", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 4", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 4", ((Integer)props.get("voidU")).intValue(), 2);

+		assertEquals("check object bind callback invocation - 4", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 4", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 4", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 4", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 4", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 4", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 4", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance2.stop();

+	}

+	

+	public void testObject() {

+		instance3.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 2);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 2);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance4.stop();

+	}

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedSimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedSimpleDependencies.java
new file mode 100644
index 0000000..489c161
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DelayedSimpleDependencies.java
@@ -0,0 +1,262 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedSimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleCheckServiceProvider").createComponentInstance(i1);

+			instance1.stop();

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidCheckServiceProvider").createComponentInstance(i2);

+			instance2.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "BothCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+		} catch(Exception e) { fail(e.getMessage()); } 

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void testSimple() {

+		instance1.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		fooProvider.stop();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		fooProvider.start();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		fooProvider.stop();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance1.stop();

+	}

+	

+	public void testVoid() {

+		instance2.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();		

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+	    assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+	    assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+	        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance2.stop();

+	}

+	

+	public void testObject() {

+		instance3.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+	    assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+	    assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+	        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance4.stop();

+	}

+	

+	public void testBoth() {

+        instance5.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        

+        instance5.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DependencyTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DependencyTestSuite.java
new file mode 100644
index 0000000..8943880
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/DependencyTestSuite.java
@@ -0,0 +1,57 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.apache.felix.ipojo.test.scenarios.dependency.di.DefaultImplementationTestSuite;

+import org.apache.felix.ipojo.test.scenarios.dependency.statics.StaticDependencyTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class DependencyTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Service Dependencies Test Suite", bc);

+		ots.addTestSuite(SimpleDependencies.class);

+		ots.addTestSuite(OptionalDependencies.class);

+		ots.addTestSuite(MultipleDependencies.class);

+		ots.addTestSuite(OptionalMultipleDependencies.class);

+		ots.addTestSuite(DelayedSimpleDependencies.class);

+		ots.addTestSuite(DelayedOptionalDependencies.class);

+		ots.addTestSuite(DelayedMultipleDependencies.class);

+		ots.addTestSuite(DelayedOptionalMultipleDependencies.class);

+        ots.addTestSuite(MethodSimpleDependencies.class);

+        ots.addTestSuite(MethodOptionalDependencies.class);

+        ots.addTestSuite(MethodMultipleDependencies.class);

+        ots.addTestSuite(MethodOptionalMultipleDependencies.class);

+        ots.addTestSuite(MethodDelayedSimpleDependencies.class);

+        ots.addTestSuite(MethodDelayedOptionalDependencies.class);

+        ots.addTestSuite(MethodDelayedMultipleDependencies.class);

+        ots.addTestSuite(MethodDelayedOptionalMultipleDependencies.class);

+        ots.addTestSuite(SimpleFilterDependencies.class);

+        ots.addTestSuite(OptionalSimpleFilterDependencies.class);

+        ots.addTestSuite(MultipleFilterDependencies.class);

+        ots.addTestSuite(OptionalMultipleFilterDependencies.class);

+        ots.addTest(StaticDependencyTestSuite.suite(bc));

+        ots.addTest(DefaultImplementationTestSuite.suite(bc));

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedMultipleDependencies.java
new file mode 100644
index 0000000..822be4b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedMultipleDependencies.java
@@ -0,0 +1,244 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodDelayedMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance3, instance4, instance5;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectMultipleCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefMultipleCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothMultipleCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+		

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+		} catch(Exception e) { fail(e.getMessage()); }

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testObject() {

+		instance3.start();

+		

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		instance4.stop();

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        instance5.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 1", ((Integer)props.get("bothU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 2);

+        assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 2);

+        assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 2.0);

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 3", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 3", ((Integer)props.get("bothU")).intValue(), 1);

+        assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        instance5.stop();

+        context.ungetService(cs_ref);

+    }

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalDependencies.java
new file mode 100644
index 0000000..72f9271
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalDependencies.java
@@ -0,0 +1,225 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodDelayedOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "MObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+            instance3.stop();

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "MRefOptionalCheckServiceProvider").createComponentInstance(i4);

+            instance4.stop();

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothOptionalCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+

+    }

+

+    public void tearDown() {

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testObject() {

+        instance3.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance3.stop();

+    }

+

+    public void testRef() {

+        instance4.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+    public void testBoth() {

+        instance5.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalMultipleDependencies.java
new file mode 100644
index 0000000..f08366b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedOptionalMultipleDependencies.java
@@ -0,0 +1,207 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodDelayedOptionalMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	

+	public void setUp() {		

+		try {

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectOptionalMultipleCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefOptionalMultipleCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+		

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+		} catch(Exception e) { fail(e.getMessage()); }		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testObject() {

+		instance3.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 2);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 2);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		instance4.stop();

+	}

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedSimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedSimpleDependencies.java
new file mode 100644
index 0000000..bc7af12
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodDelayedSimpleDependencies.java
@@ -0,0 +1,182 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodDelayedSimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectCheckServiceProvider").createComponentInstance(i3);

+			instance3.stop();

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefCheckServiceProvider").createComponentInstance(i4);

+			instance4.stop();

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+		} catch(Exception e) { fail(e.getMessage()); } 

+		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void testObject() {

+		instance3.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance3.stop();

+	}

+	

+	public void testRef() {

+		instance4.start();

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+	    assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+	    assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+	        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		

+		instance4.stop();

+	}

+	

+	public void testBoth() {

+        instance5.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        

+        instance4.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodMultipleDependencies.java
new file mode 100644
index 0000000..20cca5b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodMultipleDependencies.java
@@ -0,0 +1,305 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance3, instance4, instance5;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefMultipleCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothMultipleCheckServiceProvider").createComponentInstance(i5);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation - 1", ((Integer)props.get("bothU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 2", ((Integer)props.get("bothU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+        assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+        assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 3", ((Integer)props.get("bothB")).intValue(), 2);

+        assertEquals("check both unbind callback invocation - 3", ((Integer)props.get("bothU")).intValue(), 1);

+        assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalDependencies.java
new file mode 100644
index 0000000..e7e075f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalDependencies.java
@@ -0,0 +1,266 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+            fooProvider.stop();

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "MObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "MRefOptionalCheckServiceProvider").createComponentInstance(i4);

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothOptionalCheckServiceProvider").createComponentInstance(i5);

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+    }

+

+    public void tearDown() {

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testObject() {

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+    public void testRef() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+    

+    public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalMultipleDependencies.java
new file mode 100644
index 0000000..fa571eb
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodOptionalMultipleDependencies.java
@@ -0,0 +1,279 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodOptionalMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectOptionalMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefOptionalMultipleCheckServiceProvider").createComponentInstance(i4);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 2);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 2);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodSimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodSimpleDependencies.java
new file mode 100644
index 0000000..bf314a4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MethodSimpleDependencies.java
@@ -0,0 +1,184 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodSimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "MObjectCheckServiceProvider").createComponentInstance(i3);

+            assertNotNull("check instance 3", instance3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "MRefCheckServiceProvider").createComponentInstance(i4);

+            assertNotNull("check instance 4", instance4);

+            

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "MBothCheckServiceProvider").createComponentInstance(i5);

+            assertNotNull("check instance 5", instance5);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleDependencies.java
new file mode 100644
index 0000000..aaa401c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleDependencies.java
@@ -0,0 +1,385 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance1, instance2, instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleMultipleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidMultipleCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefMultipleCheckServiceProvider").createComponentInstance(i4);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleFilterDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleFilterDependencies.java
new file mode 100644
index 0000000..8c55bb1
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/MultipleFilterDependencies.java
@@ -0,0 +1,570 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleFilterDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+			fooProvider1.stop();

+			

+			prov = new Properties();

+            prov.put("name", "FooProvider2");

+            fooProvider2 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+            fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Subscriber1");

+			instance1 = Utils.getFactoryByName(context, "MultipleFilterCheckServiceSubscriber").createComponentInstance(i1);

+			

+			Properties i2 = new Properties();

+            i2.put("name", "Subscriber2");

+            Properties ii2 = new Properties();

+            ii2.put("id2", "(toto=A)");

+            i2.put("requires.filters", ii2);

+            instance2 = Utils.getFactoryByName(context, "MultipleFilterCheckServiceSubscriber2").createComponentInstance(i2);

+            

+            Properties i3 = new Properties();

+            i3.put("name", "Subscriber3");

+            Properties ii3 = new Properties();

+            ii3.put("id1", "(toto=A)");

+            i3.put("requires.filters", ii3);

+            instance3 = Utils.getFactoryByName(context, "MultipleFilterCheckServiceSubscriber").createComponentInstance(i3);

+		

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testMultipleNotMatch() {

+	    instance1.start();

+	    

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+

+        

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		// change the value of the property toto

+		cs.check();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 7", id.getState() == ComponentInstance.INVALID);

+		

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 9", id.getState() == ComponentInstance.INVALID);

+		

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);		

+	}

+	

+	public void testMultipleMatch() {

+	    

+	    fooProvider1.start();

+	    fooProvider2.start();

+	    

+	    ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+	    

+        instance1.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);      

+    }

+	

+	public void testMultipleNotMatchInstance() {

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 7", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 9", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);

+    }

+    

+    public void testMultipleMatchInstance() {

+        

+        fooProvider1.start();

+        fooProvider2.start();

+        instance3.start();

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+       

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);        

+    }

+	

+    public void testMultipleNotMatchInstanceWithoutFilter() {

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 7", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 9", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);

+    }

+    

+    public void testMultipleMatchInstanceWithoutFilter() {

+        fooProvider1.start();

+        fooProvider2.start();

+        instance2.start();

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+       

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);        

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalDependencies.java
new file mode 100644
index 0000000..773ea6c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalDependencies.java
@@ -0,0 +1,386 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+			

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleOptionalCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidOptionalCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefOptionalCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "BothOptionalCheckServiceProvider").createComponentInstance(i5);

+		} catch(Exception e) { fail(e.getMessage()); }		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1 ("+props.get("object")+")", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, a provider is there

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -3 ("+((Integer)props.get("voidU")) + ")", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 3", props.get("object"));

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2 (" + ((Integer)props.get("objectB")).intValue() + ")", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue()); // Nullable object.

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 1);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -3", ((Integer)props.get("bothU")).intValue(), 1);

+  

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleDependencies.java
new file mode 100644
index 0000000..91e222d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleDependencies.java
@@ -0,0 +1,499 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalMultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance1, instance2, instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleOptionalMultipleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidOptionalMultipleCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectOptionalMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefOptionalMultipleCheckServiceProvider").createComponentInstance(i4);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, it still one provider.

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 4", ((Boolean)props.get("result")).booleanValue()); // False, no more provider.

+		assertEquals("check void bind invocation - 4", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 4", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 4", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 4", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 4", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 4", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 4", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 4", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 4", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 4", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 4", ((Integer)props.get("voidB")).intValue(), 2);

+		assertEquals("check void unbind callback invocation - 4", ((Integer)props.get("voidU")).intValue(), 2);

+		assertEquals("check object bind callback invocation - 4", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 4", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 4", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 4", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 4", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 4", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 4", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 2);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 2);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 2);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 2);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 2.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 3", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 3", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 3", ((Integer)props.get("refU")).intValue(), 1);

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 0", ((Boolean)props.get("result")).booleanValue()); // False : no provider

+		assertEquals("check void bind invocation - 0", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 0", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 0", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 0", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 0", ((Integer)props.get("refB")).intValue(), 2);

+		assertEquals("check ref unbind callback invocation - 0", ((Integer)props.get("refU")).intValue(), 2);

+		assertEquals("Check FS invocation (int) - 0", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 0", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 0", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleFilterDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleFilterDependencies.java
new file mode 100644
index 0000000..5d0ae74
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalMultipleFilterDependencies.java
@@ -0,0 +1,592 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalMultipleFilterDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+			fooProvider1.stop();

+			

+			prov = new Properties();

+            prov.put("name", "FooProvider2");

+            fooProvider2 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+            fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Subscriber1");

+			instance1 = Utils.getFactoryByName(context, "OptionalMultipleFilterCheckServiceSubscriber").createComponentInstance(i1);

+			

+			Properties i2 = new Properties();

+            i2.put("name", "Subscriber2");

+            Properties ii2 = new Properties();

+            ii2.put("id2", "(toto=A)");

+            i2.put("requires.filters", ii2);

+            instance2 = Utils.getFactoryByName(context, "OptionalMultipleFilterCheckServiceSubscriber2").createComponentInstance(i2);

+            

+            Properties i3 = new Properties();

+            i3.put("name", "Subscriber3");

+            Properties ii3 = new Properties();

+            ii3.put("id1", "(toto=A)");

+            i3.put("requires.filters", ii3);

+            instance3 = Utils.getFactoryByName(context, "OptionalMultipleFilterCheckServiceSubscriber").createComponentInstance(i3);

+		

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testMultipleNotMatch() {

+	    instance1.start();

+	    

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		// change the value of the property toto

+		cs.check();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 7", id.getState() == ComponentInstance.VALID);

+		assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+		assertTrue("Check Array size - 7", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+		

+		fooProvider2.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+		

+		fooProvider2.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 9", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 9", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 9", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+		

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);		

+	}

+	

+	public void testMultipleMatch() {

+	    

+	    fooProvider1.start();

+	    fooProvider2.start();

+	    

+	    ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+	    

+        instance1.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);      

+    }

+	

+	public void testMultipleNotMatchInstance() {

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 7", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 7", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 9", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 9", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 9", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);

+    }

+    

+    public void testMultipleMatchInstance() {

+        

+        fooProvider1.start();

+        fooProvider2.start();

+        instance3.start();

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);        

+    }

+	

+    public void testMultipleNotMatchInstanceWithoutFilter() {

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        fooProvider2.start();

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        CheckService cs2 = (CheckService) context.getService(cs_ref2);

+        // change the value of the property toto

+        cs2.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        

+        // change the value of the property toto

+        cs2.check();

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 6", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 7", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 7", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 8", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 9", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 9", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 9", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        id = null;

+        cs = null;

+        cs2 = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);   

+    }

+    

+    public void testMultipleMatchInstanceWithoutFilter() {

+

+        

+        fooProvider1.start();

+        fooProvider2.start();

+        instance2.start();

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        

+        ServiceReference cs_ref2 = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref2);

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 1", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 2", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        fooProvider2.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Array size - 3", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(0)));

+        

+        fooProvider2.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertTrue("Check Array size - 4", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(1)));

+        

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(2)));

+        assertTrue("Check Array size - 5", ((Integer)cs_instance.getProps().get("Size")).equals(new Integer(2)));

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        context.ungetService(cs_ref2);      

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalSimpleFilterDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalSimpleFilterDependencies.java
new file mode 100644
index 0000000..061d08e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/OptionalSimpleFilterDependencies.java
@@ -0,0 +1,558 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalSimpleFilterDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+			fooProvider1.stop();

+			

+			prov = new Properties();

+            prov.put("name", "FooProvider2");

+            fooProvider2 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+            fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Subscriber1");

+			instance1 = Utils.getFactoryByName(context, "OptionalSimpleFilterCheckServiceSubscriber").createComponentInstance(i1);

+			

+			Properties i2 = new Properties();

+            i2.put("name", "Subscriber2");

+            Properties ii2 = new Properties();

+            ii2.put("id2", "(toto=A)");

+            i2.put("requires.filters", ii2);

+            instance2 = Utils.getFactoryByName(context, "OptionalSimpleFilterCheckServiceSubscriber2").createComponentInstance(i2);

+            

+            Properties i3 = new Properties();

+            i3.put("name", "Subscriber3");

+            Properties ii3 = new Properties();

+            ii3.put("id1", "(toto=A)");

+            i3.put("requires.filters", ii3);

+            instance3 = Utils.getFactoryByName(context, "OptionalSimpleFilterCheckServiceSubscriber").createComponentInstance(i3);

+		

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimpleNotMatch() {

+	    instance1.start();

+	    

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		// change the value of the property toto

+		cs.check();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+		assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_instance_ref);

+		cs_instance = (CheckService) context.getService(cs_instance_ref);

+		assertTrue("check CheckService invocation", cs_instance.check());

+		assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+		assertFalse("Check Nullable - 7", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+		assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+		assertTrue("Check Nullable - 8", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+		

+		id = null;

+		cs = null;

+		cs_instance = null;

+		context.ungetService(cs_instance_ref);

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testSimpleMatch() {

+	    

+	    fooProvider1.start();

+	    

+	    ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+	    

+        instance1.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+	public void testSimpleNotMatchInstance() {

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 7", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 7", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 8", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+    

+    public void testSimpleMatchInstance() {

+        

+        fooProvider1.start();

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+    public void testSimpleNotMatchInstanceWithoutFilter() {

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 7", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 7", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 7", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 8", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 8", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 8", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);      

+    }

+    

+    public void testSimpleMatchInstanceWithoutFilter() {

+

+        fooProvider1.start();

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 1", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 1", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 2", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 2", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 3", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 3", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 4", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 4", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 4", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 5", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(1)));

+        assertFalse("Check Nullable - 5", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 6", id.getState() == ComponentInstance.VALID);

+        assertTrue("Check service invocation", cs_instance.check());

+        assertTrue("Check service Binding - 6", ((Integer)cs_instance.getProps().get("Bind")).equals(new Integer(0)));

+        assertTrue("Check Nullable - 6", ((Boolean)cs_instance.getProps().get("Nullable")).booleanValue());

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleDependencies.java
new file mode 100644
index 0000000..ad02a8f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleDependencies.java
@@ -0,0 +1,319 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5, instance6;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "SimpleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "VoidCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "ObjectCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "RefCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "BothCheckServiceProvider").createComponentInstance(i5);

+            

+            Properties i6 = new Properties();

+            i6.put("name", "Double");

+            instance6 = Utils.getFactoryByName(context, "DoubleCheckServiceProvider").createComponentInstance(i6);

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		instance6.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		instance6 = null;

+		fooProvider = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		Object o = context.getService(cs_ref);

+		CheckService cs = (CheckService) o;

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1 ("+((Integer)props.get("voidB")).intValue()+")", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+	

+	public void testDouble() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance6.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance6.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        assertNotNull("Check cs", cs);

+        cs.check();

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleFilterDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleFilterDependencies.java
new file mode 100644
index 0000000..c6a2333
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/SimpleFilterDependencies.java
@@ -0,0 +1,498 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleFilterDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+			fooProvider1.stop();

+			

+			prov = new Properties();

+            prov.put("name", "FooProvider2");

+            fooProvider2 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceProvider").createComponentInstance(prov);

+            fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Subscriber1");

+			instance1 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceSubscriber").createComponentInstance(i1);

+			

+			Properties i2 = new Properties();

+            i2.put("name", "Subscriber2");

+            Properties ii2 = new Properties();

+            ii2.put("id2", "(toto=A)");

+            i2.put("requires.filters", ii2);

+            instance2 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceSubscriber2").createComponentInstance(i2);

+            

+            Properties i3 = new Properties();

+            i3.put("name", "Subscriber3");

+            Properties ii3 = new Properties();

+            ii3.put("id1", "(toto=A)");

+            i3.put("requires.filters", ii3);

+            instance3 = Utils.getFactoryByName(context, "SimpleFilterCheckServiceSubscriber").createComponentInstance(i3);

+		

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimpleNotMatch() {

+	    instance1.start();

+	    

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		// change the value of the property toto

+		cs.check();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider1.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_instance_ref);

+		cs_instance = (CheckService) context.getService(cs_instance_ref);

+		assertTrue("check CheckService invocation", cs_instance.check());

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		cs_instance = null;

+		context.ungetService(cs_instance_ref);

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testSimpleMatch() {

+	    

+	    fooProvider1.start();

+	    

+	    ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+	    

+        instance1.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+	public void testSimpleNotMatchInstance() {

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+    

+    public void testSimpleMatchInstance() {

+        

+        fooProvider1.start();

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+    public void testSimpleNotMatchInstanceWithoutFilter() {

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 4", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 5", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+    

+    public void testSimpleMatchInstanceWithoutFilter() {

+        

+        fooProvider1.start();

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        CheckService cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("Check service invocation", cs_instance.check());

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), fooProvider1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        // change the value of the property toto

+        cs.check();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider1.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs_instance_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_instance_ref);

+        cs_instance = (CheckService) context.getService(cs_instance_ref);

+        assertTrue("check CheckService invocation", cs_instance.check());

+        

+        fooProvider1.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 3", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        cs_instance = null;

+        context.ungetService(cs_instance_ref);

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DefaultImplementationTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DefaultImplementationTestSuite.java
new file mode 100644
index 0000000..fa045d7
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DefaultImplementationTestSuite.java
@@ -0,0 +1,37 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.di;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class DefaultImplementationTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Default Implementation Test Suite", bc);

+		ots.addTestSuite( OptionalDependencies.class);

+        ots.addTestSuite( MethodOptionalDependencies.class);

+        ots.addTestSuite( DelayedOptionalDependencies.class);

+        ots.addTestSuite( MethodDelayedOptionalDependencies.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DelayedOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DelayedOptionalDependencies.java
new file mode 100644
index 0000000..29a3efe
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/DelayedOptionalDependencies.java
@@ -0,0 +1,353 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.di;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DelayedOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance1, instance2, instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+    

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+

+            Properties i1 = new Properties();

+            i1.put("name", "Simple");

+            instance1 = Utils.getFactoryByName(context, "DISimpleOptionalCheckServiceProvider").createComponentInstance(i1);

+            instance1.stop();

+

+            Properties i2 = new Properties();

+            i2.put("name", "Void");

+            instance2 = Utils.getFactoryByName(context, "DIVoidOptionalCheckServiceProvider").createComponentInstance(i2);

+            instance2.stop();

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "DIObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+            instance3.stop();

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "DIRefOptionalCheckServiceProvider").createComponentInstance(i4);

+            instance4.stop();

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "DIBothOptionalCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+

+    }

+

+    public void tearDown() {

+        instance1.dispose();

+        instance2.dispose();

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance1 = null;

+        instance2 = null;

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testSimple() {

+        instance1.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 1", props.get("object"));

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation - 2", ((Boolean) props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 5);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 5);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 5.0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance1.stop();

+    }

+

+    public void testVoid() {

+        instance2.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 1", props.get("object"));

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 1);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+        assertNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 5);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 5);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 5.0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance2.stop();

+    }

+

+    public void testObject() {

+        instance3.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance3.stop();

+    }

+

+    public void testRef() {

+        instance4.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+    public void testBoth() {

+        instance5.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 1", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation - 1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation - 2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation - 2", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodDelayedOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodDelayedOptionalDependencies.java
new file mode 100644
index 0000000..4d404c7
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodDelayedOptionalDependencies.java
@@ -0,0 +1,225 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.di;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodDelayedOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "DIMObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+            instance3.stop();

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "DIMRefOptionalCheckServiceProvider").createComponentInstance(i4);

+            instance4.stop();

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "DIMBothOptionalCheckServiceProvider").createComponentInstance(i5);

+            instance5.stop();

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+

+    }

+

+    public void tearDown() {

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testObject() {

+        instance3.start();

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance3.stop();

+    }

+

+    public void testRef() {

+        instance4.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+    public void testBoth() {

+        instance5.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+

+        instance4.stop();

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodOptionalDependencies.java
new file mode 100644
index 0000000..2713fbe
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/MethodOptionalDependencies.java
@@ -0,0 +1,266 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.di;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+    

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+            fooProvider.stop();

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "DIMObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "DIMRefOptionalCheckServiceProvider").createComponentInstance(i4);

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "DIMBothOptionalCheckServiceProvider").createComponentInstance(i5);

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+    }

+

+    public void tearDown() {

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testObject() {

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 1);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+    public void testRef() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 1);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+    

+    public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 1);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/OptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/OptionalDependencies.java
new file mode 100644
index 0000000..1a1d359
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/di/OptionalDependencies.java
@@ -0,0 +1,386 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.di;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+			

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "DISimpleOptionalCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "DIVoidOptionalCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "DIObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "DIRefOptionalCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "DIBothOptionalCheckServiceProvider").createComponentInstance(i5);

+		} catch(Exception e) { fail(e.getMessage()); }		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 5);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 5);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 5.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, a provider is there

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 5);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 5);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 5.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -3 ("+((Integer)props.get("voidU")) + ")", ((Integer)props.get("voidU")).intValue(), 1);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 3", props.get("object"));

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 5);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 5);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 5.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2 (" + ((Integer)props.get("objectB")).intValue() + ")", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 1);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 1);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -2", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -3", ((Integer)props.get("bothU")).intValue(), 1);

+  

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodOptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodOptionalDependencies.java
new file mode 100644
index 0000000..310f131
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodOptionalDependencies.java
@@ -0,0 +1,266 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodOptionalDependencies extends OSGiTestCase {

+

+    ComponentInstance instance3, instance4, instance5;

+

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        try {

+            Properties prov = new Properties();

+            prov.put("name", "FooProvider");

+            fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+            fooProvider.stop();

+

+            Properties i3 = new Properties();

+            i3.put("name", "Object");

+            instance3 = Utils.getFactoryByName(context, "StaticMObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+

+            Properties i4 = new Properties();

+            i4.put("name", "Ref");

+            instance4 = Utils.getFactoryByName(context, "StaticMRefOptionalCheckServiceProvider").createComponentInstance(i4);

+

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "StaticMBothOptionalCheckServiceProvider").createComponentInstance(i5);

+        } catch (Exception e) {

+            fail(e.getMessage());

+        }

+    }

+

+    public void tearDown() {

+        instance3.dispose();

+        instance4.dispose();

+        instance5.dispose();

+        fooProvider.dispose();

+        instance3 = null;

+        instance4 = null;

+        instance5 = null;

+        fooProvider = null;

+    }

+

+    public void testObject() {

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+    public void testRef() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+    

+    public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean) props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.start();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer) props.get("bothU")).intValue(), 0);

+

+        fooProvider.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean) props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer) props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer) props.get("bothU")).intValue(), 0);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodSimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodSimpleDependencies.java
new file mode 100644
index 0000000..70fef81
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MethodSimpleDependencies.java
@@ -0,0 +1,184 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MethodSimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "StaticMObjectCheckServiceProvider").createComponentInstance(i3);

+            assertNotNull("check instance 3", instance3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "StaticMRefCheckServiceProvider").createComponentInstance(i4);

+            assertNotNull("check instance 4", instance4);

+            

+            Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "StaticMBothCheckServiceProvider").createComponentInstance(i5);

+            assertNotNull("check instance 5", instance5);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MultipleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MultipleDependencies.java
new file mode 100644
index 0000000..251adc7
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/MultipleDependencies.java
@@ -0,0 +1,307 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class MultipleDependencies extends OSGiTestCase {

+

+	ComponentInstance instance1, instance2, instance3, instance4;

+	ComponentInstance fooProvider1, fooProvider2;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider1");

+			fooProvider1 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider1.stop();

+		

+			Properties prov2 = new Properties();

+			prov2.put("name", "FooProvider2");

+			fooProvider2 = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov2);

+			fooProvider2.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "StaticSimpleMultipleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "StaticVoidMultipleCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "StaticObjectMultipleCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "StaticRefMultipleCheckServiceProvider").createComponentInstance(i4);

+		} catch(Exception e) { fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		fooProvider1 = null;

+		fooProvider2 = null;

+	}

+	

+	public void testSimple() {

+	    instance1.stop();

+	    fooProvider1.start();

+	    instance1.start();

+	    

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		

+		//Check properties

+		assertTrue("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // True, a provider is here

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider2.start();

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, two providers are here

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+		

+		fooProvider1.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void testVoid() {

+        instance2.stop();

+        fooProvider1.start();

+        instance2.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider2.start();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean) props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 2", ((Integer) props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation - 2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider1.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+	

+	public void testObject() {

+        instance3.stop();

+        fooProvider1.start();

+        instance3.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+

+        // Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider2.start();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        // Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean) props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer) props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation - 2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer) props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider1.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+	

+	public void testRef() {

+        instance4.stop();

+        fooProvider1.start();

+        instance4.start();

+

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+

+        //Check properties

+        assertTrue("check CheckService invocation - 1", ((Boolean) props.get("result")).booleanValue()); // True, a provider is here

+        assertEquals("check void bind invocation - 1", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 1", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 1", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 1", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 1", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation - 1", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 1", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 1", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 1", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider2.start();

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean) props.get("result")).booleanValue()); // True, two providers are here

+        assertEquals("check void bind invocation - 2", ((Integer) props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer) props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer) props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer) props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer) props.get("refB")).intValue(), 1);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer) props.get("refU")).intValue(), 0);

+        assertEquals("Check FS invocation (int) - 2", ((Integer) props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long) props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double) props.get("double")).doubleValue(), 1.0);

+

+        fooProvider1.stop();

+

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 5", id.getState() == ComponentInstance.INVALID);

+

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/OptionalDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/OptionalDependencies.java
new file mode 100644
index 0000000..601cd08
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/OptionalDependencies.java
@@ -0,0 +1,506 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.MissingHandlerException;

+import org.apache.felix.ipojo.UnacceptableConfiguration;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class OptionalDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+			

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "StaticSimpleOptionalCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "StaticVoidOptionalCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "StaticObjectOptionalCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "StaticRefOptionalCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "StaticBothOptionalCheckServiceProvider").createComponentInstance(i5);

+		} catch(Exception e) { fail(e.getMessage()); }		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void atestSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		

+		//Check properties

+		assertFalse("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // False, the provider was not bound

+		assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void atestDelayedSimple() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+	    instance1.stop();

+	    fooProvider.start();

+	    instance1.start();

+        

+	    ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        

+        //Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, the provider was bound

+        assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.INVALID); // Dependency broken

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+	public void atestVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation - 1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation - 1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation - 1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation - 1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation - 1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation - 1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation - 1", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 1", props.get("object"));

+		assertEquals("Check FS invocation (int) - 1", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 1", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 1", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 2", props.get("object"));

+		assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3 ("+((Integer)props.get("voidU")) + ")", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		assertNull("Check FS invocation (object) - 3", props.get("object"));

+		assertEquals("Check FS invocation (int) - 3", ((Integer)props.get("int")).intValue(), 0);

+		assertEquals("Check FS invocation (long) - 3", ((Long)props.get("long")).longValue(), 0);

+		assertEquals("Check FS invocation (double) - 3", ((Double)props.get("double")).doubleValue(), 0.0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);	

+	}

+	

+	public void testDelayedVoid() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+        instance2.stop();

+        fooProvider.start();

+        instance2.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        

+        //Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, the provider was bound

+        assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 1);

+        assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3 (" + id.getState() + ")", id.getState() == ComponentInstance.INVALID); // Dependency broken

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+	public void atestObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2 (" + ((Integer)props.get("objectB")).intValue() + ")", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);		

+	}

+	

+	public void atestDelayedObject() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {

+        instance3.stop();

+        fooProvider.start();

+        instance3.start();

+        

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        

+        //Check properties

+        assertTrue("check CheckService invocation - 2", ((Boolean)props.get("result")).booleanValue()); // True, the provider was bound

+        assertEquals("check void bind invocation - 2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation - 2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation - 2", ((Integer)props.get("objectB")).intValue(), 1);

+        assertEquals("check object unbind callback invocation - 2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation - 2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation - 2", ((Integer)props.get("refU")).intValue(), 0);

+        assertNotNull("Check FS invocation (object) - 2", props.get("object"));

+        assertEquals("Check FS invocation (int) - 2", ((Integer)props.get("int")).intValue(), 1);

+        assertEquals("Check FS invocation (long) - 2", ((Long)props.get("long")).longValue(), 1);

+        assertEquals("Check FS invocation (double) - 2", ((Double)props.get("double")).doubleValue(), 1.0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.INVALID); // Dependency broken

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);       

+    }

+	

+	public void atestRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 3", id.getState() == ComponentInstance.VALID);

+		

+		cs = (CheckService) context.getService(cs_ref);

+		props = cs.getProps();

+		//Check properties

+		assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+	}

+	

+	public void atestBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue()); // False is returned (nullable)

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.VALID);

+        

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -2", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -2", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -2", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -2", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -2", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -2", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -2", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -2", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -2", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 3 (" + id.getState() + ")", id.getState() == ComponentInstance.VALID);

+        

+        cs = (CheckService) context.getService(cs_ref);

+        props = cs.getProps();

+        //Check properties

+        assertFalse("check CheckService invocation -3", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -3", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -3", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -3", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -3", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -3", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -3", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -3", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -3", ((Integer)props.get("bothU")).intValue(), 0);

+  

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+    }

+

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/SimpleDependencies.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/SimpleDependencies.java
new file mode 100644
index 0000000..8623784
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/SimpleDependencies.java
@@ -0,0 +1,319 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class SimpleDependencies extends OSGiTestCase {

+	

+	ComponentInstance instance1, instance2, instance3, instance4, instance5;

+	ComponentInstance fooProvider;

+	

+	public void setUp() {

+		try {

+			Properties prov = new Properties();

+			prov.put("name", "FooProvider");

+			fooProvider = Utils.getFactoryByName(context, "FooProviderType-1").createComponentInstance(prov);

+			fooProvider.stop();

+		

+			Properties i1 = new Properties();

+			i1.put("name", "Simple");

+			instance1 = Utils.getFactoryByName(context, "StaticSimpleCheckServiceProvider").createComponentInstance(i1);

+		

+			Properties i2 = new Properties();

+			i2.put("name", "Void");

+			instance2 = Utils.getFactoryByName(context, "StaticVoidCheckServiceProvider").createComponentInstance(i2);

+		

+			Properties i3 = new Properties();

+			i3.put("name", "Object");

+			instance3 = Utils.getFactoryByName(context, "StaticObjectCheckServiceProvider").createComponentInstance(i3);

+		

+			Properties i4 = new Properties();

+			i4.put("name", "Ref");

+			instance4 = Utils.getFactoryByName(context, "StaticRefCheckServiceProvider").createComponentInstance(i4);

+			

+			Properties i5 = new Properties();

+            i5.put("name", "Both");

+            instance5 = Utils.getFactoryByName(context, "StaticBothCheckServiceProvider").createComponentInstance(i5);

+		} catch(Exception e) { 

+		    e.printStackTrace();

+		    fail(e.getMessage()); }

+		

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance4.dispose();

+		instance5.dispose();

+		fooProvider.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+		instance4 = null;

+		instance5 = null;

+		fooProvider = null;

+	}

+	

+	public void testSimple() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance1.getInstanceName());

+		assertNull("Check CheckService availability", cs_ref);

+		

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);

+	}

+	

+	public void testVoid() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		Object o = context.getService(cs_ref);

+		CheckService cs = (CheckService) o;

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1 ("+((Integer)props.get("voidB")).intValue()+")", ((Integer)props.get("voidB")).intValue(), 1);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+		fooProvider.stop();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance2.getInstanceName());

+        assertNull("Check CheckService availability - 2", cs_ref);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+		

+		id = null;

+		cs = null;

+		context.ungetService(arch_ref);		

+	}

+	

+	public void testObject() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 1);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance3.getInstanceName());

+        assertNull("Check CheckService availability - 2", cs_ref);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);     

+	}

+	

+	public void testRef() {

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+		

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		Properties props = cs.getProps();

+		//Check properties

+		assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+		assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+		assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+		assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+		assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+		assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 1);

+		assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+		assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 0);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance4.getInstanceName());

+        assertNull("Check CheckService availability - 2", cs_ref);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);     

+	}

+	

+	public void testBoth() {

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity", id.getState() == ComponentInstance.VALID);

+        

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        Properties props = cs.getProps();

+        //Check properties

+        assertTrue("check CheckService invocation -1", ((Boolean)props.get("result")).booleanValue());

+        assertEquals("check void bind invocation -1", ((Integer)props.get("voidB")).intValue(), 0);

+        assertEquals("check void unbind callback invocation -1", ((Integer)props.get("voidU")).intValue(), 0);

+        assertEquals("check object bind callback invocation -1", ((Integer)props.get("objectB")).intValue(), 0);

+        assertEquals("check object unbind callback invocation -1", ((Integer)props.get("objectU")).intValue(), 0);

+        assertEquals("check ref bind callback invocation -1", ((Integer)props.get("refB")).intValue(), 0);

+        assertEquals("check ref unbind callback invocation -1", ((Integer)props.get("refU")).intValue(), 0);

+        assertEquals("check both bind callback invocation -1", ((Integer)props.get("bothB")).intValue(), 1);

+        assertEquals("check both unbind callback invocation -1", ((Integer)props.get("bothU")).intValue(), 0);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        fooProvider.start();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance5.getInstanceName());

+        assertNull("Check CheckService availability - 2", cs_ref);

+        

+        fooProvider.stop();

+        

+        id = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id.getState() == ComponentInstance.INVALID);

+        

+        id = null;

+        cs = null;

+        context.ungetService(arch_ref);     

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/StaticDependencyTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/StaticDependencyTestSuite.java
new file mode 100644
index 0000000..656c635
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/dependency/statics/StaticDependencyTestSuite.java
@@ -0,0 +1,38 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.dependency.statics;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class StaticDependencyTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Static Dependency Test Suite", bc);

+		ots.addTestSuite( SimpleDependencies.class);

+		ots.addTestSuite( OptionalDependencies.class);

+		ots.addTestSuite( MultipleDependencies.class);

+		ots.addTestSuite( MethodSimpleDependencies.class);

+        ots.addTestSuite( MethodOptionalDependencies.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ConfigAdminTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ConfigAdminTest.java
new file mode 100644
index 0000000..34f5b5d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ConfigAdminTest.java
@@ -0,0 +1,143 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.test.scenarios.factory;
+
+import java.util.Properties;
+
+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;
+import org.apache.felix.ipojo.test.scenarios.service.FooService;
+import org.apache.felix.ipojo.test.scenarios.util.Utils;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+public class ConfigAdminTest extends OSGiTestCase {
+	
+	private ManagedServiceFactory getFactoryByName(String pid) {
+		ServiceReference[] refs;
+		try {
+			refs = context.getServiceReferences(ManagedServiceFactory.class.getName(), "(service.pid="+pid+")");
+			if(refs == null) { return null; }
+			return ((org.osgi.service.cm.ManagedServiceFactory) context.getService(refs[0]));
+		} catch (InvalidSyntaxException e) {
+			System.err.println("Cannot get the factory " + pid + " : " + e.getMessage());
+			return null;
+		}
+	}
+	
+	public void testCreation() {
+		ManagedServiceFactory f = getFactoryByName("FooProviderType-2");
+		
+		Properties  p = new Properties();
+		p.put("int", new Integer(3));
+		p.put("long", new Long(42));
+		p.put("string", "absdir");
+		p.put("strAProp", new String[] {"a"});
+		p.put("intAProp", new int[] {1,2});
+		
+		try {
+			f.updated("ok2", p);
+			ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "ok2");
+			assertNotNull("Check instance creation", ref);
+			f.deleted("ok2");
+			ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "ok2");
+			assertNull("Check instance deletion", ref);
+		} catch (ConfigurationException e) {
+			fail("An acceptable configuration is rejected : " + e.getMessage());
+		}
+	}
+	
+	public void testCreationString() {
+        ManagedServiceFactory f = getFactoryByName("FooProviderType-2");
+        
+        Properties  p = new Properties();
+        p.put("int", "3");
+        p.put("long", "42");
+        p.put("string", "absdir");
+        p.put("strAProp", "{a}");
+        p.put("intAProp", "{1,2}");
+        
+        try {
+            f.updated("ok2", p);
+            ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "ok2");
+            assertNotNull("Check instance creation", ref);
+            f.deleted("ok2");
+            ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "ok2");
+            assertNull("Check instance deletion", ref);
+        } catch (ConfigurationException e) {
+            fail("An acceptable configuration is rejected : " + e.getMessage());
+        }
+    }
+	
+	public void testUpdate() {
+		ManagedServiceFactory f = getFactoryByName("FooProviderType-2");
+		
+		Properties  p = new Properties();
+		p.put("int", new Integer(3));
+		p.put("long", new Long(42));
+		p.put("string", "absdir");
+		p.put("strAProp", new String[] {"a"});
+		p.put("intAProp", new int[] {1,2});
+		
+		try {
+			f.updated("okkkk", p);
+			ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+			assertNotNull("Check instance creation", ref);
+			p.put("int", new Integer("4"));
+			f.updated("okkkk", p);
+			ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+			Integer test = (Integer) ref.getProperty("int");
+			assertEquals("Check instance modification", 4, test.intValue());
+			f.deleted("okkkk");
+			ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+			assertNull("Check instance deletion", ref);
+		} catch (ConfigurationException e) {
+			fail("An acceptable configuration is rejected : " + e.getMessage());
+		}
+	}
+
+    public void testUpdateString() {
+    	ManagedServiceFactory f = getFactoryByName("FooProviderType-2");
+    	
+    	Properties  p = new Properties();
+    	p.put("int", "3");
+    	p.put("long", "42");
+    	p.put("string", "absdir");
+    	p.put("strAProp", "{a}");
+    	p.put("intAProp", "{1,2}");
+    	
+    	try {
+    		f.updated("okkkk", p);
+    		ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+    		assertNotNull("Check instance creation", ref);
+    		p.put("int", new Integer("4"));
+    		f.updated("okkkk", p);
+    		ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+    		Integer test = (Integer) ref.getProperty("int");
+    		assertEquals("Check instance modification", 4, test.intValue());
+    		f.deleted("okkkk");
+    		ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), "okkkk");
+    		assertNull("Check instance deletion", ref);
+    	} catch (ConfigurationException e) {
+    		fail("An acceptable configuration is rejected : " + e.getMessage());
+    	}
+    }
+	
+}
diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/FactoryTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/FactoryTestSuite.java
new file mode 100644
index 0000000..4c45c4c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/FactoryTestSuite.java
@@ -0,0 +1,38 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.factory;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class FactoryTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Factories Test Suite", bc);

+		

+		ots.addTestSuite( UnacceptableConfigurationTest.class);

+		ots.addTestSuite( ConfigAdminTest.class);

+		ots.addTestSuite( ObedienceTest.class);

+		

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ObedienceTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ObedienceTest.java
new file mode 100644
index 0000000..da818e4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/ObedienceTest.java
@@ -0,0 +1,66 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.factory;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentFactory;

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+

+public class ObedienceTest extends OSGiTestCase {

+

+	public void testObedience1() {

+		assertNull("Check no foo service", context.getServiceReference(FooService.class.getName()));

+		ComponentFactory factory = (ComponentFactory) Utils.getFactoryByName(context, "FooProviderType-1");

+		assertNotNull("Check factory existing", factory);

+		

+		Properties props1 = new Properties();

+		props1.put("name", "foo1");

+		Properties props2 = new Properties();

+		props2.put("name", "foo2");

+		

+		ComponentInstance ci1 = null, ci2 = null;

+		try {

+			ci1 = factory.createComponentInstance(props1);

+			ci2 = factory.createComponentInstance(props2);

+		} catch(Exception e) {

+			fail("Cannot instantiate foo providers : " + e.getMessage());

+		}

+		

+		assertTrue("Check foo1 validity", ci1.getState() == ComponentInstance.VALID);

+		assertTrue("Check foo2 validity", ci2.getState() == ComponentInstance.VALID);

+		

+		assertNotNull("Check foo service", context.getServiceReference(FooService.class.getName()));

+		assertEquals("Check the number of Foo", Utils.getServiceReferences(context, FooService.class.getName(), null).length, 2);

+		

+		factory.stop();

+		

+		assertTrue("Check foo1 invalidity ("+ci1.getState()+")", ci1.getState() == ComponentInstance.DISPOSED);

+		assertTrue("Check foo2 invalidity ("+ci1.getState()+")", ci2.getState() == ComponentInstance.DISPOSED);

+		

+		assertNull("Check no foo service", context.getServiceReference(FooService.class.getName()));

+		

+		factory.start();

+		assertNull("Check no foo service", context.getServiceReference(FooService.class.getName()));

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/UnacceptableConfigurationTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/UnacceptableConfigurationTest.java
new file mode 100644
index 0000000..797b5db
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/factory/UnacceptableConfigurationTest.java
@@ -0,0 +1,364 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.factory;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+

+public class UnacceptableConfigurationTest extends OSGiTestCase {

+

+	public void testWithoutName() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+		

+		Properties  p = new Properties();

+		p.put("int", new Integer(3));

+		p.put("long", new Long(42));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) { fail("an acceptable configuration is refused : " + e.getMessage()); }

+		

+	}

+	

+	public void testEmptyConfiguration() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+		Properties  p = new Properties();

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) { fail("An acceptable configuration is refused"); }

+	}

+	

+	public void testEmptyConfiguration2() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		Properties  p = new Properties();

+		p.put("name", "ko");

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) { return; }

+		

+		fail("An unacceptable configuration is accepted");

+	}

+	

+	public void testNull() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(null);

+			ci.dispose();

+		} catch(Exception e) { fail("An acceptable configuration is refused"); }

+	}

+	

+	public void testNull2() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(null);

+			ci.dispose();

+		} catch(Exception e) { return; }

+		

+		fail("An unacceptable configuration is accepted");

+	}

+	

+	public void testStaticOK() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("long", new Long(42));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicOK() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+		    e.printStackTrace();

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicBadType() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("long", new Long(42));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicComplete() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicJustEnough() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicMix() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDynamicUncomplete() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) { return; }

+		

+		fail("An unacceptable configuration is accepted");

+	}

+	

+	public void testDynamicMore() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		p.put("tralala", "foo");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+	

+	public void testDoubleProps() {

+		Factory f = Utils.getFactoryByName(context, "FooProviderType-Dyn2");

+		

+		Properties  p = new Properties();

+		p.put("name", "ok");

+		p.put("int", new Integer(3));

+		p.put("boolean", new Boolean(true));

+		p.put("string", "absdir");

+		p.put("strAProp", new String[] {"a"});

+		p.put("intAProp", new int[] {1,2});

+		p.put("boolean", new Boolean(false));

+		p.put("string", "toto");

+		

+		ComponentInstance ci = null;

+		try {

+			ci = f.createComponentInstance(p);

+			ci.dispose();

+		} catch(Exception e) {

+			fail("An acceptable configuration is rejected : " + e.getMessage());

+		}

+	}

+    

+    public void testUnicity1() {

+        Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+        

+        ComponentInstance ci1,ci2, ci3 = null;

+        try {

+            ci1 = f.createComponentInstance(null);

+            ci2 = f.createComponentInstance(null);

+            ci3 = f.createComponentInstance(null);

+            assertNotEquals("Check name ci1, ci2", ci1.getInstanceName(), ci2.getInstanceName());

+            assertNotEquals("Check name ci1, ci3", ci1.getInstanceName(), ci3.getInstanceName());

+            assertNotEquals("Check name ci3, ci2", ci3.getInstanceName(), ci2.getInstanceName());

+            ci1.dispose();

+            ci2.dispose();

+            ci3.dispose();

+        } catch(Exception e) { fail("An acceptable configuration is refused"); }

+    }

+    

+    public void testUnicity2() {

+        Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+        

+        ComponentInstance ci1,ci2, ci3 = null;

+        try {

+            Properties p1 = new Properties();

+            p1.put("name", "name1");

+            ci1 = f.createComponentInstance(p1);

+            Properties p2 = new Properties();

+            p2.put("name", "name2");

+            ci2 = f.createComponentInstance(p2);

+            Properties p3 = new Properties();

+            p3.put("name", "name3");

+            ci3 = f.createComponentInstance(p3);

+            assertNotEquals("Check name ci1, ci2", ci1.getInstanceName(), ci2.getInstanceName());

+            assertNotEquals("Check name ci1, ci3", ci1.getInstanceName(), ci3.getInstanceName());

+            assertNotEquals("Check name ci3, ci2", ci3.getInstanceName(), ci2.getInstanceName());

+            ci1.dispose();

+            ci2.dispose();

+            ci3.dispose();

+        } catch(Exception e) { fail("An acceptable configuration is refused"); }

+    }

+    

+    public void testUnicity3() {

+        Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+        

+        ComponentInstance ci1 = null,ci2 = null, ci3 = null;

+        try {

+            Properties p1 = new Properties();

+            p1.put("name", "name1");

+            ci1 = f.createComponentInstance(p1);

+            Properties p2 = new Properties();

+            p2.put("name", "name1");

+            ci2 = f.createComponentInstance(p2);

+            assertNotEquals("Check name ci1, ci2", ci1.getInstanceName(), ci2.getInstanceName());

+            assertNotEquals("Check name ci1, ci3", ci1.getInstanceName(), ci3.getInstanceName());

+            assertNotEquals("Check name ci3, ci2", ci3.getInstanceName(), ci3.getInstanceName());

+            ci1.dispose();

+            ci2.dispose();

+            ci3.dispose();

+        } catch(Exception e) { 

+            ci1.dispose();

+            return; }

+          

+          fail("An unacceptable configuration is acceptable");

+    }

+    

+    public void testUnicity4() {

+        Factory f = Utils.getFactoryByName(context, "FooProviderType-2");

+        Factory f2 = Utils.getFactoryByName(context, "FooProviderType-1");

+        

+        ComponentInstance ci1 = null,ci2 = null, ci3 = null;

+        try {

+            Properties p1 = new Properties();

+            p1.put("name", "name1");

+            ci1 = f.createComponentInstance(p1);

+            Properties p2 = new Properties();

+            p2.put("name", "name1");

+            ci2 = f2.createComponentInstance(p2);

+            System.err.println("==== " + ci1.getInstanceName() + " === " + ci2.getInstanceName());

+            assertNotEquals("Check name ci1, ci2", ci1.getInstanceName(), ci2.getInstanceName());

+            assertNotEquals("Check name ci1, ci3", ci1.getInstanceName(), ci3.getInstanceName());

+            assertNotEquals("Check name ci3, ci2", ci3.getInstanceName(), ci3.getInstanceName());

+            ci1.dispose();

+            ci2.dispose();

+            ci3.dispose();

+        } catch(Exception e) { 

+            ci1.dispose();

+            return; }

+          

+          fail("An unacceptable configuration is acceptable");

+    }

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/ExternalHandlerTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/ExternalHandlerTestSuite.java
new file mode 100644
index 0000000..f37d2ec
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/ExternalHandlerTestSuite.java
@@ -0,0 +1,35 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.handler;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ExternalHandlerTestSuite extends TestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("External Handler Test Suite", bc);

+		ots.addTestSuite(HandlerTest.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/HandlerTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/HandlerTest.java
new file mode 100644
index 0000000..a9d2718
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/handler/HandlerTest.java
@@ -0,0 +1,191 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.handler;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.HandlerFactory;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class HandlerTest extends OSGiTestCase {

+

+	ComponentInstance instance;

+

+	public void setUp() {

+		Properties props = new Properties();

+		props.put("name", "HandlerTest-1");

+		props.put("csh.simple", "simple");

+		Properties p = new Properties();

+		p.put("a", "a");

+		p.put("b", "b");

+		p.put("c", "c");

+		props.put("csh.map", p);

+		instance = Utils.getComponentInstance(context, "HandlerTester", props);

+	}

+	

+	public void tearDown() {

+		instance.dispose();

+		instance = null;

+	}

+	

+	public void testConfiguration1() {

+		// Check the availability of CheckService

+	    String name = "HandlerTest-1";

+		ServiceReference sr = null;

+		ServiceReference[] refs = null;

+        String filter = "("+"instance.name"+"="+name+")";

+        try {

+            refs = context.getServiceReferences(CheckService.class.getName(), filter);

+        } catch (InvalidSyntaxException e) { System.err.println("Invalid Filter : " + filter);}

+        if(refs != null) { sr = refs[0]; }

+        

+		assertNotNull("Check the check service availability", sr);

+		

+		CheckService cs = (CheckService) context.getService(sr);

+		Properties p = cs.getProps();

+		assertEquals("Assert 'simple' equality", p.get("Simple"), "simple");

+		assertEquals("Assert 'a' equality", p.get("Map1"), "a");

+		assertEquals("Assert 'b' equality", p.get("Map2"), "b");

+		assertEquals("Assert 'c' equality", p.get("Map3"), "c");

+		

+		cs = null;

+		context.ungetService(sr);

+	}

+	

+	public void testConfiguration2() {

+		// Check the availability of CheckService

+	    String name = "HandlerTest-2";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "("+"instance.name"+"="+name+")";

+        try {

+            refs = context.getServiceReferences(CheckService.class.getName(), filter);

+        } catch (InvalidSyntaxException e) { System.err.println("Invalid Filter : " + filter);}

+        if(refs != null) { sr = refs[0]; }

+		assertNotNull("Check the check service availability", sr);

+		

+		CheckService cs = (CheckService) context.getService(sr);

+		Properties p = cs.getProps();

+		assertEquals("Assert 'simple' equality", p.get("Simple"), "Simple");

+		assertEquals("Assert 'a' equality", p.get("Map1"), "a");

+		assertEquals("Assert 'b' equality", p.get("Map2"), "b");

+		assertEquals("Assert 'c' equality", p.get("Map3"), "c");

+		

+		cs = null;

+		context.ungetService(sr);

+	}

+	

+	public void testLifecycle() {

+		// Check the availability of CheckService

+	    String name = "HandlerTest-1";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "("+"instance.name"+"="+name+")";

+        try {

+            refs = context.getServiceReferences(CheckService.class.getName(), filter);

+        } catch (InvalidSyntaxException e) { System.err.println("Invalid Filter : " + filter);}

+        if(refs != null) { sr = refs[0]; }

+		assertNotNull("Check the check service availability", sr);

+		

+		ServiceReference sr_arch = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "HandlerTest-1");

+		Architecture arch = (Architecture) context.getService(sr_arch);

+		

+		assertEquals("Check instance validity - 0", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+		

+		CheckService cs = (CheckService) context.getService(sr);

+		Properties p = cs.getProps();

+		Integer changes = (Integer) p.get("changes");

+		assertNotNull("Check changes no null", changes);

+		assertEquals("Changes changes 1 ("+changes+")", changes.intValue(), 1);

+		assertEquals("Check instance validity - 1", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+		cs.check();

+		p = cs.getProps();

+		changes = (Integer) p.get("changes");

+		assertEquals("Changes changes 2 ("+changes+")", changes.intValue(), 2);

+		assertEquals("Check instance validity - 2", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

+		cs.check();

+		p = cs.getProps();

+		changes = (Integer) p.get("changes");

+		assertEquals("Changes changes 3 ("+changes+")", changes.intValue(), 3);

+		assertEquals("Check instance validity - 3", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+		cs.check();

+		p = cs.getProps();

+		changes = (Integer) p.get("changes");

+		assertEquals("Changes changes 4 ("+changes+")", changes.intValue(), 4);

+		assertEquals("Check instance validity - 4", arch.getInstanceDescription().getState(), ComponentInstance.INVALID);

+		

+		cs = null;

+		arch = null;

+		context.ungetService(sr_arch);

+		context.ungetService(sr);

+	}

+	

+	public void testAvailability() {

+	    String name = "HandlerTest-1";

+        ServiceReference sr = null;

+        ServiceReference[] refs = null;

+        String filter = "("+"instance.name"+"="+name+")";

+        try {

+            refs = context.getServiceReferences(CheckService.class.getName(), filter);

+        } catch (InvalidSyntaxException e) { System.err.println("Invalid Filter : " + filter);}

+        if(refs != null) { sr = refs[0]; }

+        assertNotNull("Check the check service availability", sr);

+        

+        ServiceReference sr_arch = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "HandlerTest-1");

+        Architecture arch = (Architecture) context.getService(sr_arch);

+        assertEquals("Check validity", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+        

+        // Kill the handler factory

+        HandlerFactory f = (HandlerFactory) Utils.getHandlerFactoryByName(context, "check");

+        f.stop();

+        

+        sr = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "HandlerTest-1");

+        assertNull("Check the check service unavailability", sr);

+        

+        sr_arch = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "HandlerTest-1");

+        assertNull("Check the architecture unavailability", sr_arch);

+        

+        // The instance is disposed, restart the handler

+        f.start();

+        

+        Properties props = new Properties();

+        props.put("name", "HandlerTest-1");

+        props.put("csh.simple", "simple");

+        Properties p = new Properties();

+        p.put("a", "a");

+        p.put("b", "b");

+        p.put("c", "c");

+        props.put("csh.map", p);

+        instance = Utils.getComponentInstance(context, "HandlerTester", props);

+        

+        sr = Utils.getServiceReferenceByName(context, CheckService.class.getName(), "HandlerTest-1");

+        assertNotNull("Check the check service availability - 2", sr);

+        

+        sr_arch = Utils.getServiceReferenceByName(context, Architecture.class.getName(), "HandlerTest-1");

+        arch = (Architecture) context.getService(sr_arch);

+        assertEquals("Check validity - 2", arch.getInstanceDescription().getState(), ComponentInstance.VALID);

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/CallbackTestCase.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/CallbackTestCase.java
new file mode 100644
index 0000000..019bec5
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/CallbackTestCase.java
@@ -0,0 +1,115 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class CallbackTestCase extends OSGiTestCase {

+	

+	ComponentInstance instance; // Instance under test

+	ComponentInstance fooProvider;

+

+	public void setUp() {

+		Properties p2 = new Properties();

+		p2.put("name", "fooProvider");

+		fooProvider = Utils.getComponentInstance(context, "FooProviderType-1", p2);

+		fooProvider.stop();

+		

+		Properties p1 = new Properties();

+		p1.put("name", "callback");

+		instance = Utils.getComponentInstance(context, "CallbackCheckService", p1);

+		

+	}

+	

+	public void tearDown() {

+		instance.dispose();

+		fooProvider.dispose();

+		instance= null;

+		fooProvider = null;

+	}

+	

+	public void testCallback() {

+		// Check instance is invalid

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+		assertEquals("Check pojo count - 1", id_dep.getCreatedObjects().length, 0);

+		

+		// Start fooprovider

+		fooProvider.start();

+		

+		// Check instance validity

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check service providing

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check int property

+		Integer index = (Integer) (cs.getProps().get("int"));

+		assertEquals("Check int property - 1", index.intValue(), 1);

+		

+		assertEquals("Check pojo count - 2", id_dep.getCreatedObjects().length, 1);

+		

+		fooProvider.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+		

+		assertEquals("Check pojo count - 3", id_dep.getCreatedObjects().length, 1);

+		

+		fooProvider.start();

+		

+		// Check instance validity

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check service providing

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Check int property

+		index = (Integer) (cs.getProps().get("int"));

+		assertEquals("Check int property - 2 ("+index.intValue()+")", index.intValue(), 3);

+		

+		assertEquals("Check pojo count - 4 ", id_dep.getCreatedObjects().length, 1);

+		

+		// Clean up

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		cs = null;

+		id_dep = null;

+	}

+		

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSeveralFactoryTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSeveralFactoryTest.java
new file mode 100644
index 0000000..19b7df9
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSeveralFactoryTest.java
@@ -0,0 +1,120 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ImmediateCallbackSeveralFactoryTest extends OSGiTestCase {

+    

+    ComponentInstance instance; // Instance under test

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        Properties p2 = new Properties();

+        p2.put("name", "fooProvider");

+        fooProvider = Utils.getComponentInstance(context, "FooProviderType-1", p2);

+        fooProvider.stop();

+        

+        Properties p1 = new Properties();

+        p1.put("name", "callback");

+        instance = Utils.getComponentInstance(context, "ImmediateCallbackCheckServiceSeveral", p1);

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        fooProvider.dispose();

+        instance= null;

+        fooProvider = null;

+        CallbackCheckService.count = 0;

+    }

+    

+    public void testCallback() {

+        // Check instance is invalid

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+        assertEquals("Check pojo count - 1", id_dep.getCreatedObjects().length, 0);

+        

+        // Start fooprovider

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        assertEquals("Check pojo count - 2", id_dep.getCreatedObjects().length, 1);

+        // Check int property

+        Integer index = (Integer) (cs.getProps().get("int"));

+        Integer count = (Integer) (cs.getProps().get("count"));

+        assertEquals("Check int property - 1 (" + index.intValue() +")", index.intValue(), 1);

+        assertEquals("Check count property - 1 (" + count.intValue() +")", count.intValue(), 1);

+        

+        fooProvider.stop();

+        

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+        

+        assertEquals("Check pojo count - 3", id_dep.getCreatedObjects().length, 1);

+        

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        // Check int property

+        index = (Integer) (cs.getProps().get("int"));

+        count = (Integer) (cs.getProps().get("count"));

+        assertEquals("Check int property - 2 ("+index.intValue()+")", index.intValue(), 3);

+        assertEquals("Check count property - 2 ("+count.intValue()+")", count.intValue(), 1);

+        

+        assertEquals("Check pojo count - 4 ", id_dep.getCreatedObjects().length, 1);

+        

+        // Clean up

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        cs = null;

+        id_dep = null;

+    }

+        

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSingletonFactoryTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSingletonFactoryTest.java
new file mode 100644
index 0000000..a86911f
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackSingletonFactoryTest.java
@@ -0,0 +1,117 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ImmediateCallbackSingletonFactoryTest extends OSGiTestCase {

+    

+    ComponentInstance instance; // Instance under test

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        Properties p2 = new Properties();

+        p2.put("name", "fooProvider");

+        fooProvider = Utils.getComponentInstance(context, "FooProviderType-1", p2);

+        fooProvider.stop();

+        

+        Properties p1 = new Properties();

+        p1.put("name", "callback");

+        instance = Utils.getComponentInstance(context, "ImmediateCallbackCheckServiceSingleton", p1);

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        fooProvider.dispose();

+        instance= null;

+        fooProvider = null;

+        CallbackCheckService.count = 0;

+        CallbackCheckService.singleton = null;

+    }

+    

+    public void testCallback() {

+        // Check instance is invalid

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+        assertEquals("Check pojo count - 1", id_dep.getCreatedObjects().length, 0);

+        

+        // Start fooprovider

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        assertEquals("Check pojo count - 2", id_dep.getCreatedObjects().length, 1);

+        // Check int property

+        Integer index = (Integer) (cs.getProps().get("int"));

+        assertEquals("Check int property - 1 (" + index.intValue() +")", index.intValue(), 1);

+        

+        fooProvider.stop();

+        

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+        

+        assertEquals("Check pojo count - 3", id_dep.getCreatedObjects().length, 1);

+        

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        // Check int property

+        index = (Integer) (cs.getProps().get("int"));

+        assertEquals("Check int property - 2 ("+index.intValue()+")", index.intValue(), 3);

+        

+        assertEquals("Check pojo count - 4 ", id_dep.getCreatedObjects().length, 1);

+        

+        // Clean up

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        cs = null;

+        id_dep = null;

+    }

+        

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackTest.java
new file mode 100644
index 0000000..dad0c1d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ImmediateCallbackTest.java
@@ -0,0 +1,114 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ImmediateCallbackTest extends OSGiTestCase {

+    

+    ComponentInstance instance; // Instance under test

+    ComponentInstance fooProvider;

+

+    public void setUp() {

+        Properties p2 = new Properties();

+        p2.put("name", "fooProvider");

+        fooProvider = Utils.getComponentInstance(context, "FooProviderType-1", p2);

+        fooProvider.stop();

+        

+        Properties p1 = new Properties();

+        p1.put("name", "callback");

+        instance = Utils.getComponentInstance(context, "ImmediateCallbackCheckService", p1);

+        

+    }

+    

+    public void tearDown() {

+        instance.dispose();

+        fooProvider.dispose();

+        instance= null;

+        fooProvider = null;

+    }

+    

+    public void testCallback() {

+        // Check instance is invalid

+        ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance.getInstanceName());

+        assertNotNull("Check architecture availability", arch_ref);

+        InstanceDescription id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+        assertEquals("Check pojo count - 1", id_dep.getCreatedObjects().length, 0);

+        

+        // Start fooprovider

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 1", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        CheckService cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        assertEquals("Check pojo count - 2", id_dep.getCreatedObjects().length, 1);

+        // Check int property

+        Integer index = (Integer) (cs.getProps().get("int"));

+        assertEquals("Check int property - 1 (" + index.intValue() +")", index.intValue(), 1);

+        

+        fooProvider.stop();

+        

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+        

+        assertEquals("Check pojo count - 3", id_dep.getCreatedObjects().length, 1);

+        

+        fooProvider.start();

+        

+        // Check instance validity

+        id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+        assertTrue("Check instance validity - 2", id_dep.getState() == ComponentInstance.VALID);

+        

+        // Check service providing

+        cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check CheckService availability", cs_ref);

+        cs = (CheckService) context.getService(cs_ref);

+        assertTrue("check CheckService invocation", cs.check());

+        

+        // Check int property

+        index = (Integer) (cs.getProps().get("int"));

+        assertEquals("Check int property - 2 ("+index.intValue()+")", index.intValue(), 3);

+        

+        assertEquals("Check pojo count - 4 ", id_dep.getCreatedObjects().length, 1);

+        

+        // Clean up

+        context.ungetService(arch_ref);

+        context.ungetService(cs_ref);

+        cs = null;

+        id_dep = null;

+    }

+        

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/LifeCycleCallbackTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/LifeCycleCallbackTest.java
new file mode 100644
index 0000000..69b171a
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/LifeCycleCallbackTest.java
@@ -0,0 +1,41 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class LifeCycleCallbackTest extends TestSuite {

+	

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Lifecycle callbacks Test Suite", bc);

+		ots.addTestSuite(CallbackTestCase.class);

+		ots.addTestSuite(ParentCallbackTestCase.class);

+        ots.addTestSuite(ImmediateCallbackTest.class);

+        ots.addTestSuite(ImmediateCallbackSingletonFactoryTest.class);

+        ots.addTestSuite(ImmediateCallbackSeveralFactoryTest.class);

+		return ots;

+	}

+

+}

+

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ParentCallbackTestCase.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ParentCallbackTestCase.java
new file mode 100644
index 0000000..1f4901c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/lifecycle/ParentCallbackTestCase.java
@@ -0,0 +1,102 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.lifecycle;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.CheckService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class ParentCallbackTestCase extends OSGiTestCase {

+	

+	ComponentInstance instance; // Instance under test

+	ComponentInstance fooProvider;

+

+	public void setUp() {

+		Properties p2 = new Properties();

+		p2.put("name", "fooProvider");

+		fooProvider = Utils.getComponentInstance(context, "FooProviderType-1", p2);

+		fooProvider.stop();

+		

+		Properties p1 = new Properties();

+		p1.put("name", "callback");

+		instance = Utils.getComponentInstance(context, "ParentCallbackCheckService", p1);

+		

+	}

+	

+	public void tearDown() {

+		instance.dispose();

+		fooProvider.dispose();

+		instance= null;

+		fooProvider = null;

+	}

+	

+	public void testCallback() {

+		// Check instance is invalid

+		ServiceReference arch_ref = Utils.getServiceReferenceByName(context, Architecture.class.getName(), instance.getInstanceName());

+		assertNotNull("Check architecture availability", arch_ref);

+		InstanceDescription id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 1", id_dep.getState() == ComponentInstance.INVALID);

+		

+		// Start fooprovider

+		fooProvider.start();

+		

+		// Check instance validity

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 1", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check service providing

+		ServiceReference cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		CheckService cs = (CheckService) context.getService(cs_ref);

+		

+		// Check int property		

+		assertEquals("Check pojo count - 2", id_dep.getCreatedObjects().length, 1);

+		

+		fooProvider.stop();

+		

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance invalidity - 2", id_dep.getState() == ComponentInstance.INVALID);

+		

+		fooProvider.start();

+		

+		// Check instance validity

+		id_dep = ((Architecture) context.getService(arch_ref)).getInstanceDescription();

+		assertTrue("Check instance validity - 2", id_dep.getState() == ComponentInstance.VALID);

+		

+		// Check service providing

+		cs_ref = Utils.getServiceReferenceByName(context, CheckService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check CheckService availability", cs_ref);

+		cs = (CheckService) context.getService(cs_ref);

+		assertTrue("check CheckService invocation", cs.check());

+		

+		// Clean up

+		context.ungetService(arch_ref);

+		context.ungetService(cs_ref);

+		cs = null;

+		id_dep = null;

+	}

+		

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ExceptionTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ExceptionTest.java
new file mode 100644
index 0000000..975e2a6
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ExceptionTest.java
@@ -0,0 +1,101 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.architecture.Architecture;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.component.FooProviderType1;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class ExceptionTest extends OSGiTestCase {

+	

+	private ComponentInstance ci_lazzy;

+	private ComponentInstance ci_immediate;

+	

+	private ServiceReference lazzyRef;

+	private ServiceReference immRef;	

+

+	public void setUp() {

+		String factName = "FooProviderType-1";

+		String compName = "FooProvider-1";

+		

+		Properties p = new Properties();

+		p.put("name", compName);

+		ci_lazzy = Utils.getComponentInstance(context, factName, p);

+		

+		String factName2 = "ImmediateFooProviderType";

+		String compName2 = "FooProvider-2";

+		

+		Properties p2 = new Properties();

+		p2.put("name", compName2);

+		ci_immediate = Utils.getComponentInstance(context, factName2, p2);

+		

+		lazzyRef = Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName+")");

+		immRef =   Utils.getServiceReference(context, Architecture.class.getName(), "(instance.name="+compName2+")");

+		assertNotNull("LazzyRef", lazzyRef);

+		assertNotNull("ImmRef", immRef);

+	}

+	

+	public void tearDown() {

+		context.ungetService(lazzyRef);

+		context.ungetService(immRef);

+		ci_lazzy.dispose();

+		ci_immediate.dispose();

+	}

+	

+    

+    public void testException() {

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy.getInstanceName() + " is available",refs);

+        FooProviderType1 fs = (FooProviderType1) context.getService(refs[0]);

+        try {

+            fs.testException();

+            context.ungetService(refs[0]);

+            fail("The method must returns an exception");

+        } catch(Exception e) {

+            context.ungetService(refs[0]);

+        }

+    }

+    

+    public void testTry() {

+        ServiceReference[] refs = null;

+        try {

+            refs = context.getServiceReferences(FooService.class.getName(), "(instance.name="+ci_lazzy.getInstanceName()+")");

+        } catch (InvalidSyntaxException e) { e.printStackTrace(); }

+        assertNotNull("Check that a FooService from " + ci_lazzy.getInstanceName() + " is available",refs);

+        FooProviderType1 fs = (FooProviderType1) context.getService(refs[0]);

+        try {

+            fs.testTry();

+            context.ungetService(refs[0]);

+        } catch(Exception e) {

+            context.ungetService(refs[0]);

+            fail("The method has returned an exception");

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/GetComponentInstanceTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/GetComponentInstanceTest.java
new file mode 100644
index 0000000..e82a011
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/GetComponentInstanceTest.java
@@ -0,0 +1,87 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.Pojo;

+import org.apache.felix.ipojo.architecture.InstanceDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class GetComponentInstanceTest extends OSGiTestCase {

+

+	public void testGetComponentInstance() {

+		String factName = "FooProviderType-1";

+		String compName = "FooProvider-1";

+		ServiceReference[] refs = null;

+		

+		// Get the facotry to create a component instance

+		Factory fact = Utils.getFactoryByName(context, factName);

+		assertNotNull("Cannot find the factory FooProvider-1", fact);

+		

+		Properties props = new Properties();

+		props.put("name", compName);

+		ComponentInstance ci = null;

+		try {

+			ci = fact.createComponentInstance(props);

+		} catch (Exception e1) { fail(e1.getMessage()); }		

+		

+		// Get a FooService provider

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), "(instance.name=" + compName + ")");

+		} catch (InvalidSyntaxException e) { fail("Service query failed (2) " + e); }

+		

+		assertNotNull("FS not available", refs);

+		

+		// Get foo object

+		FooService fs = (FooService) context.getService(refs[0]);

+		

+		// Cast to POJO

+		Pojo pojo = (Pojo) fs;

+		

+		// GetComponentInstance

+		ComponentInstance instance = pojo.getComponentInstance();

+		assertEquals("Check component instance name", instance.getInstanceName(), compName);

+		assertEquals("Check component factory name", instance.getFactory().getName(), factName);

+		assertNotNull("Instance description not null", instance.getInstanceDescription());

+		InstanceDescription id = instance.getInstanceDescription();

+		assertTrue("Check instance state", id.getState() == ComponentInstance.VALID);

+		assertEquals("Check created pojo count", id.getCreatedObjects().length, 1);

+		assertEquals("Check instance description name", id.getName(), compName); 

+		

+		// Unget the service

+		context.ungetService(refs[0]);

+		

+		ci.dispose();

+		

+		// Check that there is no more FooService

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), null);

+		} catch (InvalidSyntaxException e) { fail("Service query failed (3) : " + e.getMessage()); }

+		

+		assertNull("FS available, but component instance stopped", refs);

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadata.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadata.java
new file mode 100644
index 0000000..69c788e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadata.java
@@ -0,0 +1,237 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

+import org.apache.felix.ipojo.parser.ParseException;

+import org.apache.felix.ipojo.parser.ParseUtils;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class ManipulationMetadata extends OSGiTestCase {

+

+	public void testGetMetadata() {

+		String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+		Element elem = null;

+		try {

+			elem = ManifestMetadataParser.parse(header);

+		} catch (ParseException e) {

+			fail("Parse Exception when parsing iPOJO-Component");

+		}

+		

+		assertNotNull("Check elem not null", elem);

+		

+		Element manip = getManipulationForComponent(elem, "FooProviderType-1");

+		assertNotNull("Check manipulation metadata not null for " + "FooProviderType-1", manip);

+	}

+	

+	public void testInterface() {

+		String comp_name = "FooProviderType-1";

+		Element manip = getManipulationForComponent(comp_name);

+		Element[] itf = manip.getElements("Interface");

+		assertEquals("Check interfaces number", itf.length, 1);

+		assertEquals("Check itf name", itf[0].getAttribute("name"), FooService.class.getName());

+	}

+	

+	public void testInterfaces() {

+		String comp_name = "FooBarProviderType-1";

+		Element manip = getManipulationForComponent(comp_name);

+		Element[] itf = manip.getElements("Interface");

+		assertEquals("Check interfaces number", itf.length, 2);

+		assertEquals("Check itf name", itf[0].getAttribute("name"), FooService.class.getName());

+		assertEquals("Check itf name", itf[1].getAttribute("name"), BarService.class.getName());

+	}

+	

+	public void testFields() {

+		String comp_name = "FooProviderType-Dyn";

+		Element manip = getManipulationForComponent(comp_name);

+		Element[] fields = manip.getElements("field");

+		assertEquals("Check field count " + fields.length, fields.length, 5);

+		/*

+		private int intProp;	

+		private String strProp;

+		private String[] strAProp;

+		private int[] intAProp;

+		private boolean boolProp;

+		 */

+		

+		Element field;

+		

+		field = getFieldFromName(manip, "intProp");		

+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "intProp");

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int");

+		

+		field = getFieldFromName(manip, "strProp");

+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "strProp");

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "java.lang.String");

+		

+		field = getFieldFromName(manip, "strAProp");

+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "strAProp");

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "java.lang.String[]");

+		

+		field = getFieldFromName(manip, "intAProp");

+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "intAProp");

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int[]");

+		

+		field = getFieldFromName(manip, "boolProp");

+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "boolProp");

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean");

+	}

+	

+	public void testPrimitivesFields() {

+		String comp_name = "PrimitiveManipulationTester";

+		Element manip = getManipulationForComponent(comp_name);

+		Element[] fields = manip.getElements("Field");

+		assertEquals("Check field count", fields.length, 16);

+		/*

+		byte b = 1;

+		short s = 1;

+		int i = 1;

+		long l = 1;

+		double d = 1.1;

+		float f = 1.1f;

+		char c = 'a';

+		boolean bool = false;

+		byte[] bs = new byte[] {0,1,2};

+		short[] ss = new short[] {0,1,2};

+		int[] is = new int[] {0,1,2};

+		long[] ls = new long[] {0,1,2};

+		double[] ds = new double[] {0.0, 1.1, 2.2};

+		float[] fs = new float[] {0.0f, 1.1f, 2.2f};

+		char[] cs = new char[] {'a', 'b', 'c'};

+		boolean[] bools = new boolean[] {false, true, false};

+		 */

+		Element field;

+

+		field = getFieldFromName(manip, "b");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "byte");

+		field = getFieldFromName(manip, "s");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "short");

+		field = getFieldFromName(manip, "i");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int");

+		field = getFieldFromName(manip, "l");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "long");

+		field = getFieldFromName(manip, "d");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "double");

+		field = getFieldFromName(manip, "f");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "float");

+		field = getFieldFromName(manip, "c");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "char");

+		field = getFieldFromName(manip, "bool");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean");

+		

+		field = getFieldFromName(manip, "bs");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "byte[]");

+		field = getFieldFromName(manip, "ss");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "short[]");

+		field = getFieldFromName(manip, "is");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int[]");

+		field = getFieldFromName(manip, "ls");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "long[]");

+		field = getFieldFromName(manip, "ds");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "double[]");

+		field = getFieldFromName(manip, "fs");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "float[]");

+		field = getFieldFromName(manip, "cs");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "char[]");

+		field = getFieldFromName(manip, "bools");		

+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean[]");		

+	}

+	

+	public void testNoArgMethod() {

+		String comp_name = "SimpleMultipleCheckServiceProvider";

+		Element manip = getManipulationForComponent(comp_name);

+		Element method = getMethodFromName(manip, "check");

+		assertFalse("Check no args", method.containsAttribute("arguments"));

+		assertEquals("Check return", method.getAttribute("return"), "boolean");

+	}

+	

+	public void testOneArgsMethod() {

+		String comp_name = "SimpleMultipleCheckServiceProvider";

+		Element manip = getManipulationForComponent(comp_name);

+		Element method = getMethodFromName(manip, "refBind");

+		assertEquals("Check args", method.getAttribute("arguments"), "{org.osgi.framework.ServiceReference}");

+		assertEquals("Check args count", 1, ParseUtils.parseArrays("{org.osgi.framework.ServiceReference}").length);

+		assertFalse("Check return", method.containsAttribute("return"));

+	}

+	

+	public void testTwoArgsMethod() {

+		String comp_name = "SimpleMultipleCheckServiceProvider";

+		Element manip = getManipulationForComponent(comp_name);

+		Element method = getMethodFromName(manip, "doNothing");

+		assertEquals("Check args", method.getAttribute("arguments"), "{java.lang.Object,java.lang.String}");

+		assertEquals("Check args count", 2, ParseUtils.parseArrays("{java.lang.Object,java.lang.String}").length);

+		assertEquals("Check return", method.getAttribute("return"), "java.lang.Object");

+	}

+	

+	private Element getManipulationForComponent(Element metadata, String comp_name) {

+		Element[] comps = metadata.getElements("component");

+		for(int i = 0; i < comps.length; i++) {

+			if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {

+				return comps[i].getElements("manipulation")[0];

+			}

+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {

+                return comps[i].getElements("manipulation")[0];

+            }

+		}

+		return null;

+	}

+	

+	private Element getManipulationForComponent(String comp_name) {

+		String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+		Element elem = null;

+		try {

+			elem = ManifestMetadataParser.parse(header);

+		} catch (ParseException e) {

+			fail("Parse Exception when parsing iPOJO-Component");

+		}

+		

+		assertNotNull("Check elem not null", elem);

+		

+		Element manip = getManipulationForComponent(elem, comp_name);

+		assertNotNull("Check manipulation metadata not null for " + comp_name, manip);

+		return manip;

+	}

+	

+	private Element getMethodFromName(Element manip, String name) {

+		Element methods[] = manip.getElements("Method");

+		for(int i = 0; i < methods.length; i++) {

+			if(methods[i].containsAttribute("name") && methods[i].getAttribute("name").equals(name)) {

+				return methods[i];

+			}

+		}

+		fail("Method " + name + " not found");

+		return null;

+	}

+	

+	private Element getFieldFromName(Element manip, String name) {

+		Element fields[] = manip.getElements("Field");

+		for(int i = 0; i < fields.length; i++) {

+			if(fields[i].containsAttribute("name") && fields[i].getAttribute("name").equals(name)) {

+				return fields[i];

+			}

+		}

+		fail("Field " + name + " not found");

+		return null;

+	}

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadataAPI.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadataAPI.java
new file mode 100644
index 0000000..598267e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationMetadataAPI.java
@@ -0,0 +1,278 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.metadata.Element;

+import org.apache.felix.ipojo.parser.FieldMetadata;

+import org.apache.felix.ipojo.parser.ManifestMetadataParser;

+import org.apache.felix.ipojo.parser.MethodMetadata;

+import org.apache.felix.ipojo.parser.ParseException;

+import org.apache.felix.ipojo.parser.PojoMetadata;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+

+public class ManipulationMetadataAPI extends OSGiTestCase {

+    

+    PojoMetadata FooProviderType1, FooBarProviderType1, FooProviderTypeDyn, PrimitiveManipulationTester, SimpleMultipleCheckServiceProvider;

+

+	public void setUp() {

+        String comp_name = "FooProviderType-1";

+        FooProviderType1 = getManipulationMetadataForComponent(comp_name);

+        

+        comp_name = "FooBarProviderType-1";

+        FooBarProviderType1 = getManipulationMetadataForComponent(comp_name);

+        

+        comp_name = "FooProviderType-Dyn";

+        FooProviderTypeDyn = getManipulationMetadataForComponent(comp_name);

+        

+        comp_name = "PrimitiveManipulationTester";

+        PrimitiveManipulationTester = getManipulationMetadataForComponent(comp_name);

+        

+        comp_name = "SimpleMultipleCheckServiceProvider";

+        SimpleMultipleCheckServiceProvider = getManipulationMetadataForComponent(comp_name);

+	}

+	

+	public void testGetMetadata() {

+		String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+		Element elem = null;

+		try {

+			elem = ManifestMetadataParser.parse(header);

+		} catch (ParseException e) {

+			fail("Parse Exception when parsing iPOJO-Component");

+		}

+		

+		assertNotNull("Check elem not null", elem);

+		

+		Element manip = getMetadataForComponent(elem, "FooProviderType-1");

+        assertNotNull("Check manipulation metadata not null for " + "FooProviderType-1", manip);

+        PojoMetadata mm = new PojoMetadata(manip);

+        assertNotNull("Check mm not null", mm);

+	}

+	

+	public void testInterface() {

+	    PojoMetadata manip = FooProviderType1;

+		

+        String[] itf = manip.getInterfaces();

+		assertEquals("Check interfaces number", itf.length, 1);

+		assertEquals("Check itf name", itf[0], FooService.class.getName());

+        

+        assertTrue("Check Foo Service implementation", manip.isInterfaceImplemented(FooService.class.getName()));

+        assertFalse("Check Bar Service implementation", manip.isInterfaceImplemented(BarService.class.getName()));

+	}

+	

+	public void testInterfaces() {

+	    PojoMetadata manip = FooBarProviderType1;

+        String[] itf = manip.getInterfaces();

+		assertEquals("Check interfaces number", itf.length, 2);

+		assertEquals("Check itf name", itf[0], FooService.class.getName());

+		assertEquals("Check itf name", itf[1], BarService.class.getName());

+        

+        assertTrue("Check Foo Service implementation", manip.isInterfaceImplemented(FooService.class.getName()));

+        assertTrue("Check Bar Service implementation", manip.isInterfaceImplemented(BarService.class.getName()));

+	}

+	

+	public void testFields() {

+	    PojoMetadata manip = FooProviderTypeDyn;

+		

+		FieldMetadata[] fields = manip.getFields();

+		assertEquals("Check field count + " + fields.length, fields.length, 5);

+		/*

+		private int intProp;	

+		private String strProp;

+		private String[] strAProp;

+		private int[] intAProp;

+		private boolean boolProp;

+		 */

+		

+		FieldMetadata field;

+		

+		field = manip.getField("intProp");		

+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intProp");

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");

+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "int");

+        

+        field = manip.getField("intProp", "int");      

+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intProp");

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");

+        

+        field = manip.getField("intProp", "long");

+        assertNull("Check bad field", field);

+		

+		field = manip.getField("strProp");

+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strProp");

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String");

+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "java.lang.String");

+        

+        field = manip.getField("strProp", "String");

+        assertNull("Check bad field", field);

+        

+        field = manip.getField("strProp", "java.lang.String");

+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strProp");

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String");

+		

+		field = manip.getField("strAProp");

+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strAProp");

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String[]");

+        assertEquals("Check field reflective type : " + field.getFieldName() + " -> " + FieldMetadata.getReflectionType(field.getFieldType()), FieldMetadata.getReflectionType(field.getFieldType()), "[Ljava.lang.String;");

+        

+        field = manip.getField("strAProp", "java.lang.String[]");

+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strAProp");

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String[]");

+        

+        field = manip.getField("strAProp", "String[]");

+        assertNull("Check bad field", field);

+		

+		field = manip.getField("intAProp");

+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intAProp");

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");

+        assertEquals("Check field reflective type : " + field.getFieldName() + " -> " + FieldMetadata.getReflectionType(field.getFieldType()), FieldMetadata.getReflectionType(field.getFieldType()), "[I");

+        

+        field = manip.getField("intAProp", "int[]");

+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intAProp");

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");

+        

+        field = manip.getField("intAProp", "String[]");

+        assertNull("Check bad field", field);

+		

+		field = manip.getField("boolProp");

+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "boolProp");

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");

+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "boolean");

+        

+        field = manip.getField("boolProp", "boolean");

+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "boolProp");

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");

+        

+        field = manip.getField("boolProp", "bool");

+        assertNull("Check bad field", field);

+	}

+	

+	public void testPrimitivesFields() {

+	    PojoMetadata manip = PrimitiveManipulationTester;

+		FieldMetadata[] fields = manip.getFields();

+		assertEquals("Check field count", fields.length, 16);

+

+		FieldMetadata field;

+

+		field = manip.getField("b");		

+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "byte");

+		field = manip.getField("s");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "short");

+		field = manip.getField("i");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");

+		field = manip.getField("l");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "long");

+		field = manip.getField("d");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "double");

+		field = manip.getField("f");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "float");

+		field = manip.getField("c");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "char");

+		field = manip.getField("bool");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");

+		

+		field = manip.getField("bs");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "byte[]");

+		field = manip.getField("ss");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "short[]");

+		field = manip.getField("is");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");

+		field = manip.getField("ls");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "long[]");

+		field = manip.getField("ds");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "double[]");

+		field = manip.getField("fs");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "float[]");

+		field = manip.getField("cs");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "char[]");

+		field = manip.getField("bools");		

+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean[]");		

+	}

+	

+	public void testNoArgMethod() {

+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;

+		MethodMetadata method = manip.getMethod("check");

+		assertEquals("Check no args", method.getMethodArguments().length, 0);

+		assertEquals("Check return", method.getMethodReturn(), "boolean");

+        

+        method = manip.getMethod("check", new String[0]);

+        assertEquals("Check no args", method.getMethodArguments().length, 0);

+        assertEquals("Check return", method.getMethodReturn(), "boolean");

+	}

+	

+	public void testOneArgsMethod() {

+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;

+        MethodMetadata method = manip.getMethods("refBind")[0];

+		assertEquals("Check args count", method.getMethodArguments().length, 1);

+        assertEquals("Check args", method.getMethodArguments()[0], "org.osgi.framework.ServiceReference");

+		assertEquals("Check return", method.getMethodReturn(), "void");

+        

+        method = manip.getMethod("refBind", new String[] {"org.osgi.framework.ServiceReference"});

+        assertEquals("Check args count", method.getMethodArguments().length, 1);

+        assertEquals("Check args", method.getMethodArguments()[0], "org.osgi.framework.ServiceReference");

+        assertEquals("Check return", method.getMethodReturn(), "void");

+	}

+	

+	public void testTwoArgsMethod() {

+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;

+        MethodMetadata method = manip.getMethods("doNothing")[0];

+        assertEquals("Check args count", 2, method.getMethodArguments().length);

+		assertEquals("Check args - 1", method.getMethodArguments()[0], "java.lang.Object");

+        assertEquals("Check args - 2", method.getMethodArguments()[1], "java.lang.String");

+		assertEquals("Check return", method.getMethodReturn(), "java.lang.Object");

+        

+        method = manip.getMethod("doNothing", new String[] {"java.lang.Object", "java.lang.String"});

+        assertEquals("Check args count", 2, method.getMethodArguments().length);

+        assertEquals("Check args - 1", method.getMethodArguments()[0], "java.lang.Object");

+        assertEquals("Check args - 2", method.getMethodArguments()[1], "java.lang.String");

+        assertEquals("Check return", method.getMethodReturn(), "java.lang.Object");

+	}

+	

+	private Element getMetadataForComponent(Element metadata, String comp_name) {

+		Element[] comps = metadata.getElements("component");

+		for(int i = 0; i < comps.length; i++) {

+			if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {

+				return comps[i];

+			}

+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {

+                return comps[i];

+            }

+		}

+		return null;

+	}

+	

+    

+    private PojoMetadata getManipulationMetadataForComponent(String comp_name) {

+        String header = (String) context.getBundle().getHeaders().get("iPOJO-Components");

+        Element elem = null;

+        try {

+            elem = ManifestMetadataParser.parse(header);

+        } catch (ParseException e) {

+            fail("Parse Exception when parsing iPOJO-Component");

+        }

+        

+        assertNotNull("Check elem not null", elem);

+        

+        Element manip = getMetadataForComponent(elem, comp_name);

+        assertNotNull("Check manipulation metadata not null for " + comp_name, manip);

+        return new PojoMetadata(manip);

+    }	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationTestSuite.java
new file mode 100644
index 0000000..7bae413
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/ManipulationTestSuite.java
@@ -0,0 +1,39 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import junit.framework.Test;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.osgi.framework.BundleContext;

+

+public class ManipulationTestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Manipulation Test Suite", bc);

+		ots.addTestSuite(ManipulationMetadata.class);

+		ots.addTestSuite(PrimitiveTypeTest.class);

+		ots.addTestSuite(PrimitiveTypeTest2.class);

+		ots.addTestSuite(GetComponentInstanceTest.class);

+        ots.addTestSuite(ManipulationMetadataAPI.class);

+        ots.addTestSuite(ExceptionTest.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest.java
new file mode 100644
index 0000000..defd46e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest.java
@@ -0,0 +1,101 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.PrimitiveManipulationTestService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class PrimitiveTypeTest extends OSGiTestCase {

+

+	ComponentInstance instance; // Instance under test

+	PrimitiveManipulationTestService prim;

+	ServiceReference prim_ref;

+	

+	public void setUp() {

+		Properties p1 = new Properties();

+		p1.put("name", "primitives");

+		instance = Utils.getComponentInstance(context, "PrimitiveManipulationTester", p1);

+		assertTrue("check instance state", instance.getState() == ComponentInstance.VALID);

+		prim_ref = Utils.getServiceReferenceByName(context, PrimitiveManipulationTestService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check prim availability", prim_ref);

+		prim = (PrimitiveManipulationTestService) context.getService(prim_ref);

+	}

+	

+	public void tearDown() {

+		context.ungetService(prim_ref);

+		prim = null;

+		instance.dispose();

+		instance = null;

+	}

+	

+	public void testByte() {

+		assertEquals("Check - 1", prim.getByte(), 1);

+		prim.setByte((byte) 2);

+		assertEquals("Check - 2", prim.getByte(), 2);

+	}

+	

+	public void testShort() {

+		assertEquals("Check - 1", prim.getShort(), 1);

+		prim.setShort((short) 2);

+		assertEquals("Check - 2", prim.getShort(), 2);

+	}

+	

+	public void testInt() {

+		assertEquals("Check - 1", prim.getInt(), 1);

+		prim.setInt((int) 2);

+		assertEquals("Check - 2", prim.getInt(), 2);

+	}

+	

+	public void testLong() {

+		assertEquals("Check - 1", prim.getLong(), 1);

+		prim.setLong((long) 2);

+		assertEquals("Check - 2", prim.getLong(), 2);

+	}

+	

+	public void testFloat() {

+		assertEquals("Check - 1", prim.getFloat(), 1.1f);

+		prim.setFloat(2.2f);

+		assertEquals("Check - 2", prim.getFloat(), 2.2f);

+	}

+	

+	public void testDouble() {

+		assertEquals("Check - 1", prim.getDouble(), 1.1);

+		prim.setDouble(2.2);

+		assertEquals("Check - 2", prim.getDouble(), 2.2);

+	}

+	

+	public void testBoolean() {

+		assertFalse("Check - 1", prim.getBoolean());

+		prim.setBoolean(true);

+		assertTrue("Check - 2", prim.getBoolean());

+	}

+	

+	public void testChar() {

+		assertEquals("Check - 1", prim.getChar(), 'a');

+		prim.setChar('b');

+		assertEquals("Check - 2", prim.getChar(), 'b');

+	}

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest2.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest2.java
new file mode 100644
index 0000000..a3e7dd3
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/manipulation/PrimitiveTypeTest2.java
@@ -0,0 +1,122 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.manipulation;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.PrimitiveManipulationTestService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class PrimitiveTypeTest2 extends OSGiTestCase {

+

+    ComponentInstance instance; // Instance under test

+

+    PrimitiveManipulationTestService prim;

+

+    ServiceReference prim_ref;

+

+    public void setUp() {

+        Properties p1 = new Properties();

+        p1.put("name", "primitives");

+        instance = Utils.getComponentInstance(context, "PrimitiveManipulationTesterA", p1);

+        assertTrue("check instance state", instance.getState() == ComponentInstance.VALID);

+        prim_ref = Utils.getServiceReferenceByName(context, PrimitiveManipulationTestService.class.getName(), instance.getInstanceName());

+        assertNotNull("Check prim availability", prim_ref);

+        prim = (PrimitiveManipulationTestService) context.getService(prim_ref);

+    }

+

+    public void tearDown() {

+        context.ungetService(prim_ref);

+        prim = null;

+        instance.dispose();

+        instance = null;

+    }

+

+    public void testByte() {

+        assertEquals("Check - 1", prim.getByte(), 1);

+        prim.setByte((byte) 2);

+        assertEquals("Check - 2", prim.getByte(), 2);

+    }

+

+    public void testShort() {

+        assertEquals("Check - 1", prim.getShort(), 1);

+        prim.setShort((short) 2);

+        assertEquals("Check - 2", prim.getShort(), 2);

+    }

+

+    public void testInt() {

+        assertEquals("Check - 1", prim.getInt(), 1);

+        prim.setInt((int) 2);

+        assertEquals("Check - 2", prim.getInt(), 2);

+    }

+

+    public void testLong() {

+        assertEquals("Check - 1", prim.getLong(), 1);

+        prim.setLong((long) 2);

+        assertEquals("Check - 2", prim.getLong(), 2);

+    }

+

+    public void testLong2() {

+        assertEquals("Check - 1", prim.getLong(), 1);

+        prim.setLong(2, "ss");

+        assertEquals("Check - 2", prim.getLong(), 2);

+    }

+

+    public void testLongFromObject() {

+        assertEquals("Check - 1", prim.getLong(), 1);

+        Long l = new Long(2);

+        prim.setLong(l);

+        assertEquals("Check - 2", prim.getLong(), 2);

+    }

+

+    public void testLongFromObject2() {

+        assertEquals("Check - 1", prim.getLong(), 1);

+        Long l = new Long(2);

+        prim.setLong(l, "ss");

+        assertEquals("Check - 2", prim.getLong(), 2);

+    }

+

+    public void testFloat() {

+        assertEquals("Check - 1", prim.getFloat(), 1.1f);

+        prim.setFloat(2.2f);

+        assertEquals("Check - 2", prim.getFloat(), 2.2f);

+    }

+

+    public void testDouble() {

+        assertEquals("Check - 1", prim.getDouble(), 1.1);

+        prim.setDouble(2.2);

+        assertEquals("Check - 2", prim.getDouble(), 2.2);

+    }

+

+    public void testBoolean() {

+        assertFalse("Check - 1", prim.getBoolean());

+        prim.setBoolean(true);

+        assertTrue("Check - 2", prim.getBoolean());

+    }

+

+    public void testChar() {

+        assertEquals("Check - 1", prim.getChar(), 'a');

+        prim.setChar('b');

+        assertEquals("Check - 2", prim.getChar(), 'b');

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/A123/CheckService2.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/A123/CheckService2.java
new file mode 100644
index 0000000..6b0aafc
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/A123/CheckService2.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.A123;

+

+public interface CheckService2 {

+	

+	public boolean check();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BarService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BarService.java
new file mode 100644
index 0000000..727e845
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BarService.java
@@ -0,0 +1,29 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+import java.util.Properties;

+

+public interface BarService {

+	

+	public boolean bar();

+	

+	public Properties getProps();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BazService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BazService.java
new file mode 100644
index 0000000..115b5de
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/BazService.java
@@ -0,0 +1,39 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+import java.util.Properties;

+

+public interface BazService {

+

+	boolean foo();

+	

+	Properties fooProps();

+	

+	Boolean getObject();

+	

+	boolean getBoolean();

+	

+	int getInt();

+	

+	long getLong();

+	

+	double getDouble();

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/CheckService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/CheckService.java
new file mode 100644
index 0000000..62f254c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/CheckService.java
@@ -0,0 +1,31 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+import java.util.Properties;

+

+public interface CheckService {

+    

+    public static final String foo = "foo";

+	

+	public boolean check();

+	

+	public Properties getProps();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ChildInterface.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ChildInterface.java
new file mode 100644
index 0000000..cb7c6c1
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ChildInterface.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+public interface ChildInterface extends ParentInterface1, ParentInterface2 {

+    

+    public void processChild();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/FooService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/FooService.java
new file mode 100644
index 0000000..78693cf
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/FooService.java
@@ -0,0 +1,39 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+import java.util.Properties;

+

+public interface FooService {

+

+	boolean foo();

+	

+	Properties fooProps();

+	

+	Boolean getObject();

+	

+	boolean getBoolean();

+	

+	int getInt();

+	

+	long getLong();

+	

+	double getDouble();

+	

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface1.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface1.java
new file mode 100644
index 0000000..f70daf3
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface1.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+public interface ParentInterface1 extends ParentParentInterface {

+    

+    public void processParent1();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface2.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface2.java
new file mode 100644
index 0000000..78c3d35
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentInterface2.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+public interface ParentInterface2 {

+    

+    public void processParent2();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentParentInterface.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentParentInterface.java
new file mode 100644
index 0000000..29767d4
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/ParentParentInterface.java
@@ -0,0 +1,25 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+public interface ParentParentInterface {

+    

+    public void processParentParent();

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/PrimitiveManipulationTestService.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/PrimitiveManipulationTestService.java
new file mode 100644
index 0000000..d87118b
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/PrimitiveManipulationTestService.java
@@ -0,0 +1,75 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service;

+

+public interface PrimitiveManipulationTestService {

+	

+	byte getByte();

+	void setByte(byte b);

+	

+	short getShort();

+	void setShort(short s);

+	

+	int getInt();

+	void setInt(int i);

+	

+	long getLong();

+	void setLong(long l);

+	

+	float getFloat();

+	void setFloat(float f);

+	

+	double getDouble();

+	void setDouble(double d);

+	

+	char getChar();

+	void setChar(char c);

+	

+	boolean getBoolean();

+	void setBoolean(boolean b);

+	

+	// Array types

+	byte[] getBytes();

+	void setBytes(byte[] bs);

+	

+	short[] getShorts();

+	void setShorts(short[] ss);

+	

+	int[] getInts();

+	void setInts(int is[]);

+	

+	long[] getLongs();

+	void setLongs(long[] ls);

+	

+	float[] getFloats();

+	void setFloats(float[] fs);

+	

+	double[] getDoubles();

+	void setDoubles(double[] ds);

+	

+	char[] getChars();

+	void setChars(char[] cs);

+	

+	boolean[] getBooleans();

+	void setBooleans(boolean[] bs);	

+	

+	// This method has been added to test an issue when autoboxing.

+	void setLong(long l, String s);

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicProps.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicProps.java
new file mode 100644
index 0000000..6f615ae
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicProps.java
@@ -0,0 +1,231 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class DynamicProps extends OSGiTestCase {

+	

+	ComponentInstance fooProvider1;

+	ComponentInstance fooProvider2;

+	ComponentInstance fooProvider3;

+

+	public void setUp() {

+		String type = "FooProviderType-Dyn";

+		

+		Properties p1 = new Properties();

+		p1.put("name", "FooProvider-1");

+		fooProvider1 = Utils.getComponentInstance(context, type, p1);

+		

+		Properties p2 = new Properties();

+		p2.put("name", "FooProvider-2");

+		p2.put("int", new Integer(4));

+		p2.put("boolean", new Boolean(false));

+		p2.put("string", new String("bar"));

+		p2.put("strAProp", new String[] {"bar", "foo"});

+		p2.put("intAProp", new int[] {1, 2, 3});

+		fooProvider2 = Utils.getComponentInstance(context, type, p2);

+		

+		String type2 = "FooProviderType-Dyn2";

+		Properties p3 = new Properties();

+		p3.put("name", "FooProvider-3");

+		p3.put("int", new Integer(0));

+		p3.put("boolean", new Boolean(true));

+		p3.put("string", new String(""));

+		p3.put("strAProp", new String[0]);

+		p3.put("intAProp", new int[0]);

+		fooProvider3 = Utils.getComponentInstance(context, type2, p3);

+		

+	}

+	

+	public void tearDown() {

+		fooProvider1.dispose();

+		fooProvider1 = null;

+		fooProvider2.dispose();

+		fooProvider2 = null;

+		fooProvider3.dispose();

+		fooProvider3 = null;

+	}

+	

+	public void testProperties1() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Boolean boolProp = (Boolean) sr.getProperty("boolean");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality (1)", intProp, new Integer(2));

+		assertEquals("Check longProp equality (1)", boolProp, new Boolean(false));

+		assertEquals("Check strProp equality (1)", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity (1)", strAProp);

+		String[] v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (1)"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (1)"); }

+		}

+		

+		// Invoke

+		FooService fs = (FooService) context.getService(sr);

+		assertTrue("invoke fs", fs.foo());

+		

+		// Re-check the property (change)

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality (2)", intProp, new Integer(3));

+		assertEquals("Check longProp equality (2)", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality (2)", strProp, new String("bar"));

+		assertNotNull("Check strAProp not nullity (2)", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (2)"); }

+		}

+		assertNotNull("Check intAProp not nullity (2)", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (2)"); }

+		}

+		

+		fs = null;

+		context.ungetService(sr);

+	}

+	

+	public void testProperties2() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-2");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Boolean boolProp = (Boolean) sr.getProperty("boolean");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(4));

+		assertEquals("Check longProp equality", boolProp, new Boolean(false));

+		assertEquals("Check strProp equality", strProp, new String("bar"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"bar", "foo"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Invoke

+		FooService fs = (FooService) context.getService(sr);

+		assertTrue("invoke fs", fs.foo());

+		

+		// Re-check the property (change)

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(3));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		fs = null;

+		context.ungetService(sr);	

+	}

+	

+	public void testProperties3() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Boolean boolProp = (Boolean) sr.getProperty("boolean");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(0));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String(""));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[0];

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[0];

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Invoke

+		FooService fs = (FooService) context.getService(sr);

+		assertTrue("invoke fs", fs.foo());

+		

+		// Re-check the property (change)

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNull("Check intAProp hidding (no value)", intAProp);

+		

+		fs = null;

+		context.ungetService(sr);	

+

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicPropsReconfiguration.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicPropsReconfiguration.java
new file mode 100644
index 0000000..baeaa9d
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/DynamicPropsReconfiguration.java
@@ -0,0 +1,577 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.ConfigurationException;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+public class DynamicPropsReconfiguration extends OSGiTestCase {

+	ComponentInstance fooProvider3;

+	

+	public void setUp() {		

+		String type2 = "FooProviderType-Dyn2";

+		Properties p3 = new Properties();

+		p3.put("name", "FooProvider-3");

+		p3.put("int", new Integer(0));

+		p3.put("boolean", new Boolean(true));

+		p3.put("string", new String(""));

+		p3.put("strAProp", new String[0]);

+		p3.put("intAProp", new int[0]);

+		fooProvider3 = Utils.getComponentInstance(context, type2, p3);

+	}

+	

+	public void tearDown() {

+		fooProvider3.dispose();

+		fooProvider3 = null;

+	}

+	

+	public void testFactoryReconf() {

+    	ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	Integer intProp = (Integer) sr.getProperty("int");

+    	Boolean boolProp = (Boolean) sr.getProperty("boolean");

+    	String strProp = (String) sr.getProperty("string");

+    	String[] strAProp = (String[]) sr.getProperty("strAProp");

+    	int[] intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(0));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String(""));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	String[] v = new String[0];

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	int[] v2 = new int[0];

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}

+    	

+    	// Reconfiguration

+    	ServiceReference fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName() , "FooProviderType-Dyn2");

+    	Factory fact = (Factory) context.getService(fact_ref);

+    	Properties p3 = new Properties();

+    	p3.put("name", "FooProvider-3");

+    	p3.put("int", new Integer(1));

+    	p3.put("boolean", new Boolean(true));

+    	p3.put("string", new String("foo"));

+    	p3.put("strAProp", new String[] {"foo", "bar", "baz"});

+    	p3.put("intAProp", new int[] { 1, 2, 3});

+    	try {

+    		fact.reconfigure(p3);

+    	} catch(Exception e) {

+    		fail("Unable to reconfigure the instance with : " + p3);

+    	}

+    	

+    	sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(1));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar", "baz"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	v2 = new int[] { 1, 2, 3};

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}	

+    	

+    	// Invoke

+    	FooService fs = (FooService) context.getService(sr);

+    	assertTrue("invoke fs", fs.foo());

+    	

+    	// Re-check the property (change)

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(2));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNull("Check intAProp hidding (no value)", intAProp);

+    	

+    	//	Reconfiguration

+    	fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName() , "FooProviderType-Dyn2");

+    	fact = (Factory) context.getService(fact_ref);

+    	p3 = new Properties();

+    	p3.put("name", "FooProvider-3");

+    	p3.put("int", new Integer(1));

+    	p3.put("boolean", new Boolean(true));

+    	p3.put("string", new String("foo"));

+    	p3.put("strAProp", new String[] {"foo", "bar", "baz"});

+    	p3.put("intAProp", new int[] { 1, 2, 3});

+    	try {

+    		fact.reconfigure(p3);

+    	} catch(Exception e) {

+    		fail("Unable to reconfigure the instance with : " + p3);

+    	}

+    	

+    	sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(1));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar", "baz"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	v2 = new int[] { 1, 2, 3};

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}	

+    	

+    	fact = null;

+    	context.ungetService(fact_ref);

+    	fs = null;

+    	context.ungetService(sr);	

+    }

+

+    public void testFactoryReconfString() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Boolean boolProp = (Boolean) sr.getProperty("boolean");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(0));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String(""));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[0];

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[0];

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName() , "FooProviderType-Dyn2");

+		Factory fact = (Factory) context.getService(fact_ref);

+		Properties p3 = new Properties();

+		p3.put("name", "FooProvider-3");

+		p3.put("int", "1");

+		p3.put("boolean", "true");

+		p3.put("string", "foo");

+		p3.put("strAProp", "{foo, bar, baz}");

+		p3.put("intAProp", "{1, 2, 3}");

+		try {

+			fact.reconfigure(p3);

+		} catch(Exception e) {

+			fail("Unable to reconfigure the instance with : " + p3);

+		}

+		

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(1));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] { 1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}	

+		

+		// Invoke

+		FooService fs = (FooService) context.getService(sr);

+		assertTrue("invoke fs", fs.foo());

+		

+		// Re-check the property (change)

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNull("Check intAProp hidding (no value)", intAProp);

+		

+		//	Reconfiguration

+		fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName() , "FooProviderType-Dyn2");

+		fact = (Factory) context.getService(fact_ref);

+		p3 = new Properties();

+		p3.put("name", "FooProvider-3");

+		p3.put("int", "1");

+		p3.put("boolean", "true");

+		p3.put("string", "foo");

+		p3.put("strAProp", "{foo, bar, baz}");

+		p3.put("intAProp", "{ 1, 2, 3}");

+		try {

+			fact.reconfigure(p3);

+		} catch(Exception e) {

+			fail("Unable to reconfigure the instance with : " + p3);

+		}

+		

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(1));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] { 1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}	

+		

+		fact = null;

+		context.ungetService(fact_ref);

+		fs = null;

+		context.ungetService(sr);	

+	}

+	

+	public void testMSFReconf() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Boolean boolProp = (Boolean) sr.getProperty("boolean");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(0));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String(""));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[0];

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[0];

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName() , "FooProviderType-Dyn2");

+		ManagedServiceFactory fact = (ManagedServiceFactory) context.getService(fact_ref);

+		Properties p3 = new Properties();

+		p3.put("int", new Integer(1));

+		p3.put("boolean", new Boolean(true));

+		p3.put("string", new String("foo"));

+		p3.put("strAProp", new String[] {"foo", "bar", "baz"});

+		p3.put("intAProp", new int[] { 1, 2, 3});

+		try {

+			fact.updated("FooProvider-3", p3);

+		} catch (ConfigurationException e) {

+			fail("Unable to reconfigure the instance with : " + p3);

+		}

+		

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(1));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] { 1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}	

+		

+		// Invoke

+		FooService fs = (FooService) context.getService(sr);

+		assertTrue("invoke fs", fs.foo());

+		

+		// Re-check the property (change)

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNull("Check intAProp hidding (no value)", intAProp);

+		

+		//	Reconfiguration

+		fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName() , "FooProviderType-Dyn2");

+		fact = (ManagedServiceFactory) context.getService(fact_ref);

+		p3 = new Properties();

+		p3.put("int", new Integer(1));

+		p3.put("boolean", new Boolean(true));

+		p3.put("string", new String("foo"));

+		p3.put("strAProp", new String[] {"foo", "bar", "baz"});

+		p3.put("intAProp", new int[] { 1, 2, 3});

+		try {

+			fact.updated("FooProvider-3", p3);

+		} catch (ConfigurationException e) {

+			fail("Unable to reconfigure the instance with : " + p3);

+		}

+		

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		intProp = (Integer) sr.getProperty("int");

+		boolProp = (Boolean) sr.getProperty("boolean");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(1));

+		assertEquals("Check longProp equality", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] { 1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}	

+		

+		fact = null;

+		context.ungetService(fact_ref);

+		fs = null;

+		context.ungetService(sr);	

+	}

+

+    public void testMSFReconfString() {

+    	ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	Integer intProp = (Integer) sr.getProperty("int");

+    	Boolean boolProp = (Boolean) sr.getProperty("boolean");

+    	String strProp = (String) sr.getProperty("string");

+    	String[] strAProp = (String[]) sr.getProperty("strAProp");

+    	int[] intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(0));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String(""));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	String[] v = new String[0];

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	int[] v2 = new int[0];

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}

+    	

+    	// Reconfiguration

+    	ServiceReference fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName() , "FooProviderType-Dyn2");

+    	ManagedServiceFactory fact = (ManagedServiceFactory) context.getService(fact_ref);

+    	Properties p3 = new Properties();

+    	p3.put("int", "1");

+    	p3.put("boolean", "true");

+    	p3.put("string", "foo");

+    	p3.put("strAProp", "{foo, bar, baz}");

+    	p3.put("intAProp", "{ 1, 2, 3}");

+    	try {

+    		fact.updated("FooProvider-3", p3);

+    	} catch (ConfigurationException e) {

+    		fail("Unable to reconfigure the instance with : " + p3);

+    	}

+    	

+    	sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(1));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar", "baz"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	v2 = new int[] { 1, 2, 3};

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}	

+    	

+    	// Invoke

+    	FooService fs = (FooService) context.getService(sr);

+    	assertTrue("invoke fs", fs.foo());

+    	

+    	// Re-check the property (change)

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(2));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNull("Check intAProp hidding (no value)", intAProp);

+    	

+    	//	Reconfiguration

+    	fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName() , "FooProviderType-Dyn2");

+    	fact = (ManagedServiceFactory) context.getService(fact_ref);

+    	p3 = new Properties();

+    	p3.put("int", "1");

+        p3.put("boolean", "true");

+        p3.put("string", "foo");

+        p3.put("strAProp", "{foo, bar, baz}");

+        p3.put("intAProp", "{ 1, 2, 3}");

+    	try {

+    		fact.updated("FooProvider-3", p3);

+    	} catch (ConfigurationException e) {

+    		fail("Unable to reconfigure the instance with : " + p3);

+    	}

+    	

+    	sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-3");

+    	assertNotNull("Check the availability of the FS service", sr);

+    	

+    	// Check service properties

+    	intProp = (Integer) sr.getProperty("int");

+    	boolProp = (Boolean) sr.getProperty("boolean");

+    	strProp = (String) sr.getProperty("string");

+    	strAProp = (String[]) sr.getProperty("strAProp");

+    	intAProp = (int[]) sr.getProperty("intAProp");

+    	

+    	assertEquals("Check intProp equality", intProp, new Integer(1));

+    	assertEquals("Check longProp equality", boolProp, new Boolean(true));

+    	assertEquals("Check strProp equality", strProp, new String("foo"));

+    	assertNotNull("Check strAProp not nullity", strAProp);

+    	v = new String[] {"foo", "bar", "baz"};

+    	for (int i = 0; i < strAProp.length; i++) {

+    		if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+    	}

+    	assertNotNull("Check intAProp not nullity", intAProp);

+    	v2 = new int[] { 1, 2, 3};

+    	for (int i = 0; i < intAProp.length; i++) {

+    		if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+    	}	

+    	

+    	fact = null;

+    	context.ungetService(fact_ref);

+    	fs = null;

+    	context.ungetService(sr);	

+    }

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/Exposition.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/Exposition.java
new file mode 100644
index 0000000..ee7aca2
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/Exposition.java
@@ -0,0 +1,193 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class Exposition extends OSGiTestCase {

+	

+	private ComponentInstance fooProviderSimple;

+	private ComponentInstance fooProviderItf;

+	private ComponentInstance fooBarProvider;

+	private ComponentInstance fooBarProvider2;

+	private ComponentInstance fooBarProvider3;

+	

+	public void setUp(){ 

+		Properties p1 = new Properties();

+		p1.put("name", "fooProviderSimple");

+		fooProviderSimple = Utils.getComponentInstance(context, "FooProviderType-1", p1);

+		

+		Properties p2 = new Properties();

+		p2.put("name", "fooProviderItf");

+		fooProviderItf = Utils.getComponentInstance(context, "FooProviderType-itf", p2);

+		

+		Properties p3 = new Properties();

+		p3.put("name", "fooProviderItfs");

+		fooBarProvider = Utils.getComponentInstance(context, "FooBarProviderType-1", p3);

+		

+		Properties p4 = new Properties();

+		p4.put("name", "fooProviderItfs2");

+		fooBarProvider2 = Utils.getComponentInstance(context, "FooBarProviderType-2", p4);

+		

+		Properties p5 = new Properties();

+		p5.put("name", "fooProviderItfs3");

+		fooBarProvider3 = Utils.getComponentInstance(context, "FooBarProviderType-3", p5);

+		

+		assertNotNull("Check the instance creation of fooProviderSimple", fooProviderSimple);

+		assertNotNull("Check the instance creation of fooProviderItf", fooProviderItf);

+		assertNotNull("Check the instance creation of fooProviderItfs", fooBarProvider);

+		assertNotNull("Check the instance creation of fooProviderItfs2", fooBarProvider2);

+		assertNotNull("Check the instance creation of fooProviderItfs3", fooBarProvider3);

+		

+	}

+	

+	public void tearDown() {

+		fooProviderSimple.dispose();

+		fooProviderItf.dispose();

+		fooBarProvider.dispose();

+		fooBarProvider2.dispose();

+		fooBarProvider3.dispose();

+		fooProviderSimple = null;

+		fooProviderItf = null;

+		fooBarProvider = null;

+		fooBarProvider2 = null;

+		fooBarProvider3 = null;		

+	}

+	

+	public void testSimpleExposition() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooProviderSimple.getInstanceName());

+		assertNotNull("Check the availability of the FS from "+fooProviderSimple.getInstanceName(), ref);

+		FooService fs = (FooService) context.getService(ref);

+		assertTrue("Check fs invocation", fs.foo());

+		fs = null;

+		context.ungetService(ref);

+		fooProviderSimple.stop();

+		ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooProviderSimple.getInstanceName());

+		assertNull("Check the absence of the FS from "+fooProviderSimple.getInstanceName(), ref);

+		

+	}

+	

+	public void testItfExposition() {

+		ServiceReference ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooProviderItf.getInstanceName());

+		assertNotNull("Check the availability of the FS from "+fooProviderItf.getInstanceName(), ref);

+		FooService fs = (FooService) context.getService(ref);

+		assertTrue("Check fs invocation", fs.foo());

+		fs = null;

+		context.ungetService(ref);

+		fooProviderItf.stop();

+		

+		ref = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooProviderItf.getInstanceName());

+		assertNull("Check the absence of the FS from "+fooProviderItf.getInstanceName(), ref);

+	}

+	

+	public void testItfsExposition() {

+		ServiceReference refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider.getInstanceName());

+		assertNotNull("Check the availability of the FS from "+fooBarProvider.getInstanceName(), refFoo);

+		ServiceReference refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider.getInstanceName());

+		assertNotNull("Check the availability of the BS from "+fooBarProvider.getInstanceName(), refBar);

+		

+		assertSame("Check service reference equality", refFoo, refBar);

+		

+		FooService fs = (FooService) context.getService(refFoo);

+		assertTrue("Check fs invocation", fs.foo());

+		fs = null;

+		context.ungetService(refFoo);

+		

+		BarService bs = (BarService) context.getService(refBar);

+		assertTrue("Check bs invocation", bs.bar());

+		bs = null;

+		context.ungetService(refBar);

+		

+		fooBarProvider.stop();

+		

+		refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider.getInstanceName());

+		refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider.getInstanceName());

+		assertNull("Check the absence of the FS from "+fooBarProvider.getInstanceName(), refFoo);

+		assertNull("Check the absence of the BS from "+fooBarProvider.getInstanceName(), refBar);

+	}

+	

+	public void testItfsExposition2() {

+		ServiceReference refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider2.getInstanceName());

+		assertNotNull("Check the availability of the FS from "+fooBarProvider2.getInstanceName(), refFoo);

+		ServiceReference refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider2.getInstanceName());

+		assertNotNull("Check the availability of the BS from "+fooBarProvider2.getInstanceName(), refBar);

+		

+		assertSame("Check service reference equality", refFoo, refBar);

+		

+		FooService fs = (FooService) context.getService(refFoo);

+		assertTrue("Check fs invocation", fs.foo());

+		fs = null;

+		context.ungetService(refFoo);

+		

+		BarService bs = (BarService) context.getService(refBar);

+		assertTrue("Check bs invocation", bs.bar());

+		bs = null;

+		context.ungetService(refBar);

+		

+		fooBarProvider2.stop();

+		

+		refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider2.getInstanceName());

+		refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider2.getInstanceName());

+		assertNull("Check the absence of the FS from "+fooBarProvider.getInstanceName(), refFoo);

+		assertNull("Check the absence of the BS from "+fooBarProvider.getInstanceName(), refBar);

+	}

+	

+	public void testItfsExposition3() {

+		ServiceReference refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider3.getInstanceName());

+		assertNotNull("Check the availability of the FS from "+fooBarProvider3.getInstanceName(), refFoo);

+		ServiceReference refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider3.getInstanceName());

+		assertNotNull("Check the availability of the BS from "+fooBarProvider3.getInstanceName(), refBar);

+		

+		assertNotSame("Check service reference inequality", refFoo, refBar);

+		

+		FooService fs = (FooService) context.getService(refFoo);

+		assertTrue("Check fs invocation", fs.foo());

+		fs = null;

+		context.ungetService(refFoo);

+		

+		BarService bs = (BarService) context.getService(refBar);

+		assertTrue("Check bs invocation", bs.bar());

+		bs = null;

+		context.ungetService(refBar);

+		

+		// Check properties

+		String baz1 = (String) refFoo.getProperty("baz");

+		String baz2 = (String) refBar.getProperty("baz");

+		

+		assertEquals("Check Baz Property 1", baz1, "foo");

+		assertEquals("Check Baz Property 2", baz2, "bar");

+		

+		fooBarProvider3.stop();

+		

+		refFoo = Utils.getServiceReferenceByName(context, FooService.class.getName(), fooBarProvider3.getInstanceName());

+		refBar = Utils.getServiceReferenceByName(context, BarService.class.getName(), fooBarProvider3.getInstanceName());

+		assertNull("Check the absence of the FS from "+fooBarProvider.getInstanceName(), refFoo);

+		assertNull("Check the absence of the BS from "+fooBarProvider.getInstanceName(), refBar);

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/FactoryProps.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/FactoryProps.java
new file mode 100644
index 0000000..0be3205
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/FactoryProps.java
@@ -0,0 +1,87 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.architecture.PropertyDescription;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.BarService;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class FactoryProps extends OSGiTestCase {

+	

+//	public void testImplementationClass() {

+//		ServiceReference ref1 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-1");

+//		assertNotNull("The factory is available", ref1);

+//		String clazz = (String) ref1.getProperty("component.class");

+//		assertEquals("Check the implementation class", clazz, FooProviderType1.class.getName());

+//	}

+	

+	public void testSimpleExposition() {

+		ServiceReference ref1 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-1");

+		assertNotNull("The factory is available", ref1);

+		String[] spec = (String[]) ref1.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check array length", spec.length, 1);

+		assertEquals("Check spec", spec[0], FooService.class.getName());

+	}

+	

+	public void testDoubleExposition() {

+		ServiceReference ref1 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooBarProviderType-1");

+		assertNotNull("The factory is available", ref1);

+		String[] spec = (String[]) ref1.getProperty("component.providedServiceSpecifications");

+		assertEquals("Check array length", spec.length, 2);

+		assertContains("Check spec 1", spec, FooService.class.getName());

+		assertContains("Check spec 2", spec, BarService.class.getName());

+	}

+	

+	public void testProps() {

+		ServiceReference ref1 = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-Dyn2");

+		assertNotNull("The factory is available", ref1);

+		PropertyDescription[] pd = (PropertyDescription[]) ref1.getProperty("component.properties");

+		assertEquals("Check property list size", pd.length, 5);

+		

+		//P0

+		assertEquals("0) Check name", "int", pd[0].getName());

+		assertEquals("0) Check type", "int", pd[0].getType());

+		assertEquals("0) Check value", "4", pd[0].getValue());

+		

+		//P1

+		assertEquals("1) Check name", "boolean", pd[1].getName());

+		assertEquals("1) Check type", "boolean", pd[1].getType());

+		assertNull("1) Check value", pd[1].getValue());

+		

+		//P2

+		assertEquals("2) Check name", "string", pd[2].getName());

+		assertEquals("2) Check type",  String.class.getName(), pd[2].getType());

+		assertNull("2) Check value", pd[2].getValue());

+		

+		//P3

+		assertEquals("3) Check name", "strAProp", pd[3].getName());

+		assertEquals("3) Check type", "java.lang.String[]", pd[3].getType());

+		assertNull("3) Check value", pd[3].getValue());

+		

+		//P4

+		assertEquals("4) Check name", "intAProp", pd[4].getName());

+		assertEquals("4) Check type", "int[]", pd[4].getType());

+	}

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/ProvidedServiceTestSuite.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/ProvidedServiceTestSuite.java
new file mode 100644
index 0000000..d12c206
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/ProvidedServiceTestSuite.java
@@ -0,0 +1,43 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import junit.framework.Test;

+import junit.framework.TestSuite;

+

+import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite;

+import org.apache.felix.ipojo.test.scenarios.service.providing.inherited.InheritedTest;

+import org.osgi.framework.BundleContext;

+

+public class ProvidedServiceTestSuite extends TestSuite {

+

+	public static Test suite(BundleContext bc) {

+		OSGiTestSuite ots = new OSGiTestSuite("Provided Service Test Suite", bc);

+		ots.addTestSuite(Exposition.class);

+		ots.addTestSuite(SimplePS.class);

+		ots.addTestSuite(StaticProps.class);

+		ots.addTestSuite(DynamicProps.class);

+		ots.addTestSuite(FactoryProps.class);

+		ots.addTestSuite(StaticPropsReconfiguration.class);

+		ots.addTestSuite(DynamicPropsReconfiguration.class);

+		ots.addTestSuite(InheritedTest.class);

+		return ots;

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/SimplePS.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/SimplePS.java
new file mode 100644
index 0000000..8e52b1c
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/SimplePS.java
@@ -0,0 +1,80 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+

+public class SimplePS extends OSGiTestCase {

+	

+	public void testPS() {

+		String factName = "FooProviderType-1";

+		String compName = "FooProvider-1";

+		ServiceReference[] refs = null;

+		

+		// Check that no Foo Service are available

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), null);

+		} catch (InvalidSyntaxException e) { fail("Service query failed : " + e); }

+		

+		assertNull("FS already available", refs);

+	

+		// Get the factory to create a component instance

+		Factory fact = Utils.getFactoryByName(context, factName);

+		assertNotNull("Cannot find the factory FooProvider-1", fact);

+		

+		Properties props = new Properties();

+		props.put("name", compName);

+		ComponentInstance ci = null;

+		try {

+			ci = fact.createComponentInstance(props);

+		} catch (Exception e1) { fail(e1.getMessage()); }		

+		

+		// Get a FooService provider

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), "(" + "instance.name" + "=" + compName + ")");

+		} catch (InvalidSyntaxException e) { fail("Service query failed (2) " + e); }

+		

+		assertNotNull("FS not available", refs);

+		

+		// Test foo invocation

+		FooService fs = (FooService) context.getService(refs[0]);

+		assertTrue("FooService invocation failed", fs.foo());

+		

+		// Unget the service

+		context.ungetService(refs[0]);

+		

+		ci.dispose();

+		

+		// Check that there is no more FooService

+		try {

+			refs = context.getServiceReferences(FooService.class.getName(), null);

+		} catch (InvalidSyntaxException e) { fail("Service query failed (3) : " + e.getMessage()); }

+		

+		assertNull("FS available, but component instance stopped", refs);

+	}

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticProps.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticProps.java
new file mode 100644
index 0000000..4894900
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticProps.java
@@ -0,0 +1,112 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class StaticProps extends OSGiTestCase {

+	

+	ComponentInstance fooProvider1;

+	ComponentInstance fooProvider2;

+	

+	public void setUp() {

+		String type = "FooProviderType-2";

+		

+		Properties p1 = new Properties();

+		p1.put("name", "FooProvider-1");

+		fooProvider1 = Utils.getComponentInstance(context, type, p1);

+		

+		Properties p2 = new Properties();

+		p2.put("name", "FooProvider-2");

+		p2.put("int", new Integer(4));

+		p2.put("long", new Long(42));

+		p2.put("string", new String("bar"));

+		p2.put("strAProp", new String[] {"bar", "foo"});

+		p2.put("intAProp", new int[] {1, 2, 3});

+		fooProvider2 = Utils.getComponentInstance(context, type, p2);

+		

+	}

+	

+	public void tearDown() {

+		fooProvider1.dispose();

+		fooProvider1 = null;

+		fooProvider2.dispose();

+		fooProvider2 = null;

+	}

+	

+	public void testProperties1() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", longProp, new Long(40));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		       

+	}

+	

+	public void testProperties2() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-2");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(4));

+		assertEquals("Check longProp equality", longProp, new Long(42));

+		assertEquals("Check strProp equality", strProp, new String("bar"));

+

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"bar", "foo"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+	}

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticPropsReconfiguration.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticPropsReconfiguration.java
new file mode 100644
index 0000000..215d41e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/StaticPropsReconfiguration.java
@@ -0,0 +1,337 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.ConfigurationException;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+public class StaticPropsReconfiguration extends OSGiTestCase {

+

+	ComponentInstance fooProvider1;

+	ComponentInstance fooProvider2;

+

+	public void setUp() {

+		String type = "FooProviderType-2";

+		

+		Properties p1 = new Properties();

+		p1.put("name", "FooProvider-1");

+		fooProvider1 = Utils.getComponentInstance(context, type, p1);

+		

+		Properties p2 = new Properties();

+		p2.put("name", "FooProvider-2");

+		p2.put("int", new Integer(4));

+		p2.put("long", new Long(42));

+		p2.put("string", new String("bar"));

+		p2.put("strAProp", new String[] {"bar", "foo"});

+		p2.put("intAProp", new int[] {1, 2, 3});

+		fooProvider2 = Utils.getComponentInstance(context, type, p2);

+		

+	}

+	

+	public void tearDown() {

+		fooProvider1.dispose();

+		fooProvider1 = null;

+		fooProvider2.dispose();

+		fooProvider2 = null;

+	}

+	

+	public void testReconfFactory1() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", longProp, new Long(40));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-2");

+		Dictionary reconf = new Properties();

+		reconf.put("name", "FooProvider-1");

+		reconf.put("int", new Integer(5));

+		reconf.put("long", new Long(43));

+		reconf.put("string", new String("toto"));

+		reconf.put("strAProp", new String[] {"foo", "baz"});

+		reconf.put("intAProp", new int[] {3, 2, 1});

+		Factory fact = (Factory) context.getService(fact_ref);

+		try {

+			fact.reconfigure(reconf);

+		} catch(Exception e) {

+			fail("Configuration non acceptable : " + reconf);

+		}

+

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties after the reconfiguration

+		intProp = (Integer) sr.getProperty("int");

+		longProp = (Long) sr.getProperty("long");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality after reconfiguration", intProp, new Integer(5));

+		assertEquals("Check longProp equality after reconfiguration", longProp, new Long(43));

+		assertEquals("Check strProp equality after reconfiguration", strProp, new String("toto"));

+		assertNotNull("Check strAProp not nullity after reconfiguration", strAProp);

+		v = new String[] {"foo", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		context.ungetService(fact_ref);

+		fact = null;

+		       

+	}

+	

+	public void testReconfFactory2() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-2");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(4));

+		assertEquals("Check longProp equality", longProp, new Long(42));

+		assertEquals("Check strProp equality", strProp, new String("bar"));

+

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"bar", "foo"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, Factory.class.getName(), "FooProviderType-2");

+		Dictionary reconf = new Properties();

+		reconf.put("name", "FooProvider-2");

+		reconf.put("int", new Integer(5));

+		reconf.put("long", new Long(43));

+		reconf.put("string", new String("toto"));

+		reconf.put("strAProp", new String[] {"foo", "baz"});

+		reconf.put("intAProp", new int[] {3, 2, 1});

+		Factory fact = (Factory) context.getService(fact_ref);

+		try {

+			fact.reconfigure(reconf);

+		} catch(Exception e) {

+			fail("Configuration non acceptable : " + reconf);

+		}

+		

+		// Check service properties after the reconfiguration

+		intProp = (Integer) sr.getProperty("int");

+		longProp = (Long) sr.getProperty("long");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality after reconfiguration", intProp, new Integer(5));

+		assertEquals("Check longProp equality after reconfiguration", longProp, new Long(43));

+		assertEquals("Check strProp equality after reconfiguration", strProp, new String("toto"));

+		assertNotNull("Check strAProp not nullity after reconfiguration", strAProp);

+		v = new String[] {"foo", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		context.ungetService(fact_ref);

+		fact = null;

+	}

+	

+	public void testMSFFactory1() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(2));

+		assertEquals("Check longProp equality", longProp, new Long(40));

+		assertEquals("Check strProp equality", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"foo", "bar"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), "FooProviderType-2");

+		Dictionary reconf = new Properties();

+		reconf.put("int", new Integer(5));

+		reconf.put("long", new Long(43));

+		reconf.put("string", new String("toto"));

+		reconf.put("strAProp", new String[] {"foo", "baz"});

+		reconf.put("intAProp", new int[] {3, 2, 1});

+		ManagedServiceFactory fact = (ManagedServiceFactory) context.getService(fact_ref);

+		try {

+			fact.updated("FooProvider-1", reconf);

+		} catch (ConfigurationException e) {

+			fail("Configuration non acceptable : " + reconf);

+		}

+

+		sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-1");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties after the reconfiguration

+		intProp = (Integer) sr.getProperty("int");

+		longProp = (Long) sr.getProperty("long");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality after reconfiguration", intProp, new Integer(5));

+		assertEquals("Check longProp equality after reconfiguration", longProp, new Long(43));

+		assertEquals("Check strProp equality after reconfiguration", strProp, new String("toto"));

+		assertNotNull("Check strAProp not nullity after reconfiguration", strAProp);

+		v = new String[] {"foo", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		context.ungetService(fact_ref);

+		fact = null;

+		       

+	}

+	

+	public void testReconfMSF2() {

+		ServiceReference sr = Utils.getServiceReferenceByName(context, FooService.class.getName(), "FooProvider-2");

+		assertNotNull("Check the availability of the FS service", sr);

+		

+		// Check service properties

+		Integer intProp = (Integer) sr.getProperty("int");

+		Long longProp = (Long) sr.getProperty("long");

+		String strProp = (String) sr.getProperty("string");

+		String[] strAProp = (String[]) sr.getProperty("strAProp");

+		int[] intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality", intProp, new Integer(4));

+		assertEquals("Check longProp equality", longProp, new Long(42));

+		assertEquals("Check strProp equality", strProp, new String("bar"));

+

+		assertNotNull("Check strAProp not nullity", strAProp);

+		String[] v = new String[] {"bar", "foo"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		// Reconfiguration

+		ServiceReference fact_ref = Utils.getServiceReferenceByName(context, ManagedServiceFactory.class.getName(), "FooProviderType-2");

+		Dictionary reconf = new Properties();

+		reconf.put("int", new Integer(5));

+		reconf.put("long", new Long(43));

+		reconf.put("string", new String("toto"));

+		reconf.put("strAProp", new String[] {"foo", "baz"});

+		reconf.put("intAProp", new int[] {3, 2, 1});

+		ManagedServiceFactory fact = (ManagedServiceFactory) context.getService(fact_ref);

+		try {

+			fact.updated("FooProvider-2", reconf);

+		} catch (ConfigurationException e) {

+			fail("Configuration non acceptable : " + reconf);

+		}

+		

+		// Check service properties after the reconfiguration

+		intProp = (Integer) sr.getProperty("int");

+		longProp = (Long) sr.getProperty("long");

+		strProp = (String) sr.getProperty("string");

+		strAProp = (String[]) sr.getProperty("strAProp");

+		intAProp = (int[]) sr.getProperty("intAProp");

+		

+		assertEquals("Check intProp equality after reconfiguration", intProp, new Integer(5));

+		assertEquals("Check longProp equality after reconfiguration", longProp, new Long(43));

+		assertEquals("Check strProp equality after reconfiguration", strProp, new String("toto"));

+		assertNotNull("Check strAProp not nullity after reconfiguration", strAProp);

+		v = new String[] {"foo", "baz"};

+		for (int i = 0; i < strAProp.length; i++) {

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		v2 = new int[] {3, 2, 1};

+		for (int i = 0; i < intAProp.length; i++) {

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+		}

+		

+		context.ungetService(fact_ref);

+		fact = null;

+	}

+	

+	

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/inherited/InheritedTest.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/inherited/InheritedTest.java
new file mode 100644
index 0000000..a2c52f3
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/service/providing/inherited/InheritedTest.java
@@ -0,0 +1,193 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.service.providing.inherited;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.service.ChildInterface;

+import org.apache.felix.ipojo.test.scenarios.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.service.ParentInterface1;

+import org.apache.felix.ipojo.test.scenarios.service.ParentInterface2;

+import org.apache.felix.ipojo.test.scenarios.service.ParentParentInterface;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class InheritedTest extends OSGiTestCase {

+    

+    private Factory pi1, pi11, pi12, pi2, pi21, pi3;

+    

+    public void setUp() {

+        pi1 = Utils.getFactoryByName(context, "PI1");

+        pi11 = Utils.getFactoryByName(context, "PI1-1");

+        pi12 = Utils.getFactoryByName(context, "PI1-2");

+        

+        pi2 = Utils.getFactoryByName(context, "PI2");

+        pi21 = Utils.getFactoryByName(context, "PI2-1");

+        

+        pi3 = Utils.getFactoryByName(context, "PI3");

+    }

+    

+    private boolean contains(String[] arr, String txt) {

+        for (int i = 0; i < arr.length; i++) {

+            if (arr[i].equals(txt)) {

+                return true;

+            }

+        }

+        return false;

+    }

+    

+    public void testPI1Factory() {

+        String[] specs = pi1.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count", specs.length, 4);

+        assertTrue("Check Child", contains(specs, ChildInterface.class.getName()));

+        assertTrue("Check Parent1", contains(specs, ParentInterface1.class.getName()));

+        assertTrue("Check Parent2", contains(specs, ParentInterface2.class.getName()));

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+    }

+    

+    public void testPI11Factory() {

+        String[] specs = pi11.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count", specs.length, 1);

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+    }

+    

+    public void testPI12Factory() {

+        String[] specs = pi12.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count", specs.length, 2);

+        assertTrue("Check Parent2", contains(specs, ParentInterface2.class.getName()));

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+    }

+    

+    public void testPI2Factory() {

+        String[] specs = pi2.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count ("+specs.length+")", specs.length, 4);

+        assertTrue("Check Child", contains(specs, ChildInterface.class.getName()));

+        assertTrue("Check Parent1", contains(specs, ParentInterface1.class.getName()));

+        assertTrue("Check Parent2", contains(specs, ParentInterface2.class.getName()));

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+    }

+    

+    public void testPI21Factory() {

+        String[] specs = pi21.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count", specs.length, 1);

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+    }

+    

+    public void testPI3Factory() {

+        String[] specs = pi3.getComponentDescription().getprovidedServiceSpecification();

+        assertEquals("Check provides count", specs.length, 5);

+        assertTrue("Check Child", contains(specs, ChildInterface.class.getName()));

+        assertTrue("Check Parent1", contains(specs, ParentInterface1.class.getName()));

+        assertTrue("Check Parent2", contains(specs, ParentInterface2.class.getName()));

+        assertTrue("Check ParentParent", contains(specs, ParentParentInterface.class.getName()));

+        assertTrue("Check FS", contains(specs, FooService.class.getName()));

+    }

+    

+    public void testIP1() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi1.getName(), "ci");

+        

+        ServiceReference ref1 = Utils.getServiceReferenceByName(context, ChildInterface.class.getName(), "ci");

+        assertNotNull("Check Child", ref1);

+        

+        ServiceReference ref2 = Utils.getServiceReferenceByName(context, ParentInterface1.class.getName(), "ci");

+        assertNotNull("Check Parent1", ref2);

+        

+        ServiceReference ref3 = Utils.getServiceReferenceByName(context, ParentInterface2.class.getName(), "ci");

+        assertNotNull("Check Parent2", ref3);

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ci.dispose();

+    }

+    

+    public void testIP11() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi11.getName(), "ci");

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ci.dispose();

+    }

+    

+    public void testIP12() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi12.getName(), "ci");

+        

+        ServiceReference ref3 = Utils.getServiceReferenceByName(context, ParentInterface2.class.getName(), "ci");

+        assertNotNull("Check Parent2", ref3);

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ci.dispose();

+    }

+    

+    public void testIP2() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi2.getName(), "ci");

+        

+        ServiceReference ref1 = Utils.getServiceReferenceByName(context, ChildInterface.class.getName(), "ci");

+        assertNotNull("Check Child", ref1);

+        

+        ServiceReference ref2 = Utils.getServiceReferenceByName(context, ParentInterface1.class.getName(), "ci");

+        assertNotNull("Check Parent1", ref2);

+        

+        ServiceReference ref3 = Utils.getServiceReferenceByName(context, ParentInterface2.class.getName(), "ci");

+        assertNotNull("Check Parent2", ref3);

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ci.dispose();

+    }

+    

+    public void testIP21() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi21.getName(), "ci");

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ci.dispose();

+    }

+    

+    public void testIP3() {

+        ComponentInstance ci = Utils.getComponentInstanceByName(context, pi3.getName(), "ci");

+        

+        ServiceReference ref1 = Utils.getServiceReferenceByName(context, ChildInterface.class.getName(), "ci");

+        assertNotNull("Check Child", ref1);

+        

+        ServiceReference ref2 = Utils.getServiceReferenceByName(context, ParentInterface1.class.getName(), "ci");

+        assertNotNull("Check Parent1", ref2);

+        

+        ServiceReference ref3 = Utils.getServiceReferenceByName(context, ParentInterface2.class.getName(), "ci");

+        assertNotNull("Check Parent2", ref3);

+        

+        ServiceReference ref4 = Utils.getServiceReferenceByName(context, ParentParentInterface.class.getName(), "ci");

+        assertNotNull("Check PP", ref4);

+        

+        ServiceReference ref5 = Utils.getServiceReferenceByName(context, FooService.class.getName(), "ci");

+        assertNotNull("Check FS", ref5);

+        

+        ci.dispose();

+    }

+    

+    

+    

+

+}

diff --git a/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java
new file mode 100644
index 0000000..9b0b8db
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java
@@ -0,0 +1,289 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.util;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

+import junit.framework.Assert;

+

+import org.apache.felix.ipojo.ComponentInstance;

+import org.apache.felix.ipojo.Factory;

+import org.apache.felix.ipojo.Handler;

+import org.apache.felix.ipojo.HandlerFactory;

+import org.apache.felix.ipojo.ServiceContext;

+//import org.apache.felix.ipojo.composite.CompositeManager;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.InvalidSyntaxException;

+import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.ManagedServiceFactory;

+

+public class Utils {

+

+    public static Factory getFactoryByName(BundleContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(factory.name=" + factoryName + ")");

+            if (refs == null) {

+                System.err.println("Cannot get the factory " + factoryName);

+                return null;

+            }

+            return ((Factory) bc.getService(refs[0]));

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static HandlerFactory getHandlerFactoryByName(BundleContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(" + Handler.HANDLER_NAME_PROPERTY + "=" + factoryName + ")");

+            if (refs == null) {

+                System.err.println("Cannot get the factory " + factoryName);

+                return null;

+            }

+            return (HandlerFactory) bc.getService(refs[0]);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static ComponentInstance getComponentInstance(BundleContext bc, String factoryName, Dictionary configuration) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) {

+            System.err.println("Factory " + factoryName + " not found");

+            return null;

+        }

+

+        // if(fact.isAcceptable(configuration)) {

+        try {

+            return fact.createComponentInstance(configuration);

+        } catch (Exception e) {

+            Assert.fail("Cannot create the instance from " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+        // }

+        // else {

+        // System.err.println("Configuration not accepted by : " + factoryName);

+        // return null;

+        // }

+    }

+

+    public static ComponentInstance getComponentInstanceByName(BundleContext bc, String factoryName, String name) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) {

+            System.err.println("Factory " + factoryName + " not found");

+            return null;

+        }

+

+        try {

+            Properties props = new Properties();

+            props.put("name", name);

+            return fact.createComponentInstance(props);

+        } catch (Exception e) {

+            System.err.println("Cannot create the instance from " + factoryName + " : " + e.getMessage());

+            e.printStackTrace();

+            return null;

+        }

+    }

+

+    public static ServiceReference[] getServiceReferences(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return new ServiceReference[0];

+        } else {

+            return refs;

+        }

+    }

+

+    public static ServiceReference getServiceReference(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static ServiceReference getServiceReferenceByName(BundleContext bc, String itf, String name) {

+        ServiceReference[] refs = null;

+        String filter = null;

+        if (itf.equals(Factory.class.getName()) || itf.equals(ManagedServiceFactory.class.getName())) {

+            filter = "(" + "factory.name" + "=" + name + ")";

+        } else {

+            filter = "(" + "instance.name" + "=" + name + ")";

+        }

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static Object getServiceObject(BundleContext bc, String itf, String filter) {

+        ServiceReference ref = getServiceReference(bc, itf, filter);

+        if (ref != null) {

+            return bc.getService(ref);

+        } else {

+            return null;

+        }

+    }

+

+    public static Object[] getServiceObjects(BundleContext bc, String itf, String filter) {

+        ServiceReference[] refs = getServiceReferences(bc, itf, filter);

+        if (refs != null) {

+            Object[] list = new Object[refs.length];

+            for (int i = 0; i < refs.length; i++) {

+                list[i] = bc.getService(refs[i]);

+            }

+            return list;

+        } else {

+            return new Object[0];

+        }

+    }

+

+//    public static ServiceContext getServiceContext(ComponentInstance ci) {

+//        if (ci instanceof CompositeManager) {

+//            return ((CompositeManager) ci).getServiceContext();

+//        } else {

+//            throw new RuntimeException("Cannot get the service context form an non composite instance");

+//        }

+//    }

+

+    public static Factory getFactoryByName(ServiceContext bc, String factoryName) {

+        ServiceReference[] refs;

+        try {

+            refs = bc.getServiceReferences(Factory.class.getName(), "(factory.name=" + factoryName + ")");

+            if (refs == null) { return null; }

+            return ((Factory) bc.getService(refs[0]));

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Cannot get the factory " + factoryName + " : " + e.getMessage());

+            return null;

+        }

+    }

+

+    public static ComponentInstance getComponentInstance(ServiceContext bc, String factoryName, Dictionary configuration) {

+        Factory fact = getFactoryByName(bc, factoryName);

+

+        if (fact == null) { return null; }

+

+        if (fact.isAcceptable(configuration)) {

+            try {

+                return fact.createComponentInstance(configuration);

+            } catch (Exception e) {

+                System.err.println(e.getMessage());

+                e.printStackTrace();

+                return null;

+            }

+        } else {

+            System.err.println("Configuration not accepted by : " + factoryName);

+            return null;

+        }

+    }

+

+    public static ServiceReference[] getServiceReferences(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return new ServiceReference[0];

+        } else {

+            return refs;

+        }

+    }

+

+    public static ServiceReference getServiceReference(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = null;

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static ServiceReference getServiceReferenceByName(ServiceContext bc, String itf, String name) {

+        ServiceReference[] refs = null;

+        String filter = null;

+        if (itf.equals(Factory.class.getName()) || itf.equals(ManagedServiceFactory.class.getName())) {

+            filter = "(" + "factory.name" + "=" + name + ")";

+        } else {

+            filter = "(" + "instance.name" + "=" + name + ")";

+        }

+        try {

+            refs = bc.getServiceReferences(itf, filter);

+        } catch (InvalidSyntaxException e) {

+            System.err.println("Invalid Filter : " + filter);

+        }

+        if (refs == null) {

+            return null;

+        } else {

+            return refs[0];

+        }

+    }

+

+    public static Object getServiceObject(ServiceContext bc, String itf, String filter) {

+        ServiceReference ref = getServiceReference(bc, itf, filter);

+        if (ref != null) {

+            return bc.getService(ref);

+        } else {

+            return null;

+        }

+    }

+

+    public static Object[] getServiceObjects(ServiceContext bc, String itf, String filter) {

+        ServiceReference[] refs = getServiceReferences(bc, itf, filter);

+        if (refs != null) {

+            Object[] list = new Object[refs.length];

+            for (int i = 0; i < refs.length; i++) {

+                list[i] = bc.getService(refs[i]);

+            }

+            return list;

+        } else {

+            return new Object[0];

+        }

+    }

+

+}

diff --git a/ipojo/tests/tests.core/src/main/resources/metadata.xml b/ipojo/tests/tests.core/src/main/resources/metadata.xml
new file mode 100644
index 0000000..4d6ff5e
--- /dev/null
+++ b/ipojo/tests/tests.core/src/main/resources/metadata.xml
@@ -0,0 +1,1105 @@
+<ipojo

+	xmlns:cs="org.apache.felix.ipojo.test.handler.CheckServiceHandler">

+	<component classname="org.apache.felix.ipojo.test.log.LogImpl"

+		factory="true" name="log">

+		<provides />

+	</component>

+

+	<!-- Component Types used inside tests -->

+	<!--  Service Providing -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-1" architecture="true">

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-1-Sing" factory-method="singleton"

+		architecture="true">

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-1-Sev" factory-method="several"

+		architecture="true">

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-1-SingM" factory-method="singleton"

+		architecture="true">

+		<provides factory="method" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-1-SevM" factory-method="several"

+		architecture="true">

+		<provides factory="method" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		name="FooProviderType-2" architecture="true">

+		<provides>

+			<property name="int" type="int" value="2" />

+			<property name="long" type="long" value="40" />

+			<property name="string" type="java.lang.String" value="foo" />

+			<property name="strAProp" type="java.lang.String[]"

+				value="{foo, bar}" />

+			<property name="intAProp" type="int[]" value="{1,2,3}" />

+		</provides>

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"

+		name="FooProviderType-Dyn" architecture="true">

+		<provides>

+			<property name="int" field="intProp" value="2" />

+			<property name="boolean" field="boolProp" value="false" />

+			<property name="string" field="strProp" value="foo" />

+			<property name="strAProp" field="strAProp"

+				value="{foo, bar}" />

+			<property name="intAProp" field="intAProp" value="{ 1,2,3}" />

+		</provides>

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn2"

+		name="FooProviderType-Dyn2" factory="true" architecture="true">

+		<provides>

+			<property name="int" field="intProp" value="4" />

+			<property name="boolean" field="boolProp" />

+			<property name="string" field="strProp" />

+			<property name="strAProp" field="strAProp" />

+			<property name="intAProp" field="intAProp"

+				value="{1, 2,3 }" />

+		</provides>

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"

+		factory="FooProviderType-Conf" architecture="true">

+		<provides />

+		<properties propagation="false">

+			<property name="int" field="intProp" value="2" />

+			<property name="boolean" field="boolProp" value="false" />

+			<property name="string" field="strProp" value="foo" />

+			<property name="strAProp" field="strAProp"

+				value="{foo, bar}" />

+			<property name="intAProp" field="intAProp" value="{1,2, 3}" />

+		</properties>

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-3" architecture="true">

+		<provides>

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+			<property name="baz" type="java.lang.String" />

+		</provides>

+		<properties propagation="true">

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+		</properties>

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="FooProviderType-itf" architecture="true">

+		<provides

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"

+		factory="FooBarProviderType-1" architecture="true">

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"

+		factory="FooBarProviderType-2" architecture="true">

+		<provides

+			interface="{org.apache.felix.ipojo.test.scenarios.service.FooService, org.apache.felix.ipojo.test.scenarios.service.BarService }" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooBarProviderType1"

+		factory="FooBarProviderType-3" architecture="true">

+		<provides

+			interface="{org.apache.felix.ipojo.test.scenarios.service.FooService}">

+			<property name="baz" type="java.lang.String" value="foo" />

+		</provides>

+		<provides

+			interface="{org.apache.felix.ipojo.test.scenarios.service.BarService}">

+			<property name="baz" type="java.lang.String" value="bar" />

+		</provides>

+	</component>

+

+	<!-- Immediate Component -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="ImmediateFooProviderType" immediate="true"

+		architecture="true">

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="ImmediateFooProviderTypeSingleton" immediate="true"

+		factory-method="singleton" architecture="true">

+		<provides />

+	</component>

+

+	<!--  Simple Filter Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FilterCheckProvider"

+		factory="SimpleFilterCheckServiceProvider" architecture="true">

+		<provides>

+			<property field="m_toto" name="toto" value="A" />

+		</provides>

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FilterCheckSubscriber"

+		factory="SimpleFilterCheckServiceSubscriber" architecture="true">

+		<requires field="m_foo" filter="(toto=B)" id="id1">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FilterCheckSubscriber"

+		factory="SimpleFilterCheckServiceSubscriber2" architecture="true">

+		<requires field="m_foo" id="id2">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!--  Optional Simple Filter Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FilterCheckSubscriber"

+		factory="OptionalSimpleFilterCheckServiceSubscriber"

+		architecture="true">

+		<requires field="m_foo" filter="(toto=B)" id="id1"

+			optional="true">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FilterCheckSubscriber"

+		factory="OptionalSimpleFilterCheckServiceSubscriber2"

+		architecture="true">

+		<requires field="m_foo" id="id2" optional="true">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Aggregate filter Dependencies-->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleFilterCheckSubscriber"

+		factory="MultipleFilterCheckServiceSubscriber" architecture="true">

+		<requires field="m_foo" filter="(toto=B)" id="id1">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleFilterCheckSubscriber"

+		factory="MultipleFilterCheckServiceSubscriber2" architecture="true">

+		<requires field="m_foo" id="id2">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!--  Optional Aggregate Filter Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleFilterCheckSubscriber"

+		factory="OptionalMultipleFilterCheckServiceSubscriber"

+		architecture="true">

+		<requires field="m_foo" filter="(toto=B)" id="id1"

+			optional="true">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleFilterCheckSubscriber"

+		factory="OptionalMultipleFilterCheckServiceSubscriber2"

+		architecture="true">

+		<requires field="m_foo" id="id2" optional="true">

+			<callback type="bind" method="Bind" />

+			<callback type="unbind" method="Unbind" />

+		</requires>

+		<provides />

+	</component>

+

+

+	<!--  Simple Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="SimpleCheckServiceProvider" architecture="true">

+		<requires field="fs" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="VoidCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="ObjectCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="RefCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="BothCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DoubleCheckServiceProvider" architecture="true">

+		<requires>

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<requires field="fs" />

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MObjectCheckServiceProvider" architecture="true">

+		<requires>

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MRefCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MBothCheckServiceProvider" architecture="true">

+		<requires>

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Simple & Optional Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="SimpleOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="VoidOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="ObjectOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="RefOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="BothOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MObjectOptionalCheckServiceProvider" architecture="true">

+		<requires optional="true">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MRefOptionalCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="MBothOptionalCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Simple & Optional Dependencies with default-implementation -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DISimpleOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DIVoidOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DIObjectOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DIRefOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="DIBothOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="DIMObjectOptionalCheckServiceProvider" architecture="true">

+		<requires optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="DIMRefOptionalCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="DIMBothOptionalCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true"

+			default-implementation="org.apache.felix.ipojo.test.scenarios.component.FooServiceDefaultImpl">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!--  Multiple Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="SimpleMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="VoidMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="ObjectMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="RefMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="BothMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="MObjectMultipleCheckServiceProvider" architecture="true">

+		<requires aggregate="true">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="MRefMultipleCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			aggregate="true">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="MBothMultipleCheckServiceProvider" architecture="true">

+		<requires aggregate="true">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Multiple & Optional Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="SimpleOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="VoidOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="ObjectOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="RefOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="MObjectOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires aggregate="true" optional="true">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="MRefOptionalMultipleCheckServiceProvider"

+		architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			aggregate="true" optional="true">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Static Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticSimpleCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticVoidCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticObjectCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticRefCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticBothCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMObjectCheckServiceProvider" architecture="true">

+		<requires policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMRefCheckServiceProvider" architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMBothCheckServiceProvider" architecture="true">

+		<requires policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+	<!-- Static Simple & Optional Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticSimpleOptionalCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true" policy="static" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticVoidOptionalCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true" policy="static">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticObjectOptionalCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true" policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticRefOptionalCheckServiceProvider" architecture="true">

+		<requires field="fs" optional="true" policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"

+		factory="StaticBothOptionalCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" optional="true" policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMObjectOptionalCheckServiceProvider"

+		architecture="true">

+		<requires optional="true" policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMRefOptionalCheckServiceProvider"

+		architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true" policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodCheckServiceProvider"

+		factory="StaticMBothOptionalCheckServiceProvider"

+		architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			optional="true" policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<!--  Static Multiple Dependencies -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="StaticSimpleMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" policy="static" />

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="StaticVoidMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="voidBind" />

+			<callback type="unbind" method="voidUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="StaticObjectMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="StaticRefMultipleCheckServiceProvider" architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"

+		factory="StaticBothMultipleCheckServiceProvider"

+		architecture="true">

+		<requires field="fs" policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="StaticMObjectMultipleCheckServiceProvider"

+		architecture="true">

+		<requires aggregate="true" policy="static">

+			<callback type="bind" method="objectBind" />

+			<callback type="unbind" method="objectUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="StaticMRefMultipleCheckServiceProvider"

+		architecture="true">

+		<requires

+			interface="org.apache.felix.ipojo.test.scenarios.service.FooService"

+			aggregate="true" policy="static">

+			<callback type="bind" method="refBind" />

+			<callback type="unbind" method="refUnbind" />

+		</requires>

+		<provides />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"

+		factory="StaticMBothMultipleCheckServiceProvider"

+		architecture="true">

+		<requires aggregate="true" policy="static">

+			<callback type="bind" method="bothBind" />

+			<callback type="unbind" method="bothUnbind" />

+		</requires>

+		<provides />

+	</component>

+

+

+	<!-- Lifecycle Callback -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService"

+		factory="CallbackCheckService" architecture="true">

+		<requires field="fs" />

+		<provides />

+		<callback transition="validate" method="start" />

+		<callback transition="invalidate" method="stop" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService"

+		factory="ParentCallbackCheckService" architecture="true">

+		<requires field="fs" />

+		<provides />

+		<callback transition="validate" method="parentStart" />

+		<callback transition="invalidate" method="parentStop" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService"

+		immediate="true" factory="ImmediateCallbackCheckService"

+		architecture="true">

+		<requires field="fs" />

+		<provides />

+		<callback transition="validate" method="start" />

+		<callback transition="invalidate" method="stop" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService"

+		immediate="true" factory="ImmediateCallbackCheckServiceSingleton"

+		factory-method="singleton" architecture="true">

+		<requires field="fs" />

+		<provides />

+		<callback transition="validate" method="start" />

+		<callback transition="invalidate" method="stop" />

+	</component>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.CallbackCheckService"

+		immediate="true" factory="ImmediateCallbackCheckServiceSeveral"

+		factory-method="several" architecture="true">

+		<requires field="fs" />

+		<provides />

+		<callback transition="validate" method="start" />

+		<callback transition="invalidate" method="stop" />

+	</component>

+

+	<!-- Manipulation -->

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.Manipulation23Tester"

+		factory="PrimitiveManipulationTester" architecture="true">

+		<provides />

+	</component>

+

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.A123.Manipulation23Tester"

+		factory="PrimitiveManipulationTesterA" architecture="true">

+		<provides />

+	</component>

+

+	<!-- Configuration Management Test -->

+	<component factory="FieldConfigurableCheckService"

+		className="org.apache.felix.ipojo.test.scenarios.component.ConfigurableCheckServiceProvider"

+		architecture="true">

+		<provides />

+		<properties propagation="true">

+			<property field="b" />

+			<property field="s" />

+			<property field="i" />

+			<property field="l" />

+			<property field="d" />

+			<property field="f" />

+			<property field="c" />

+			<property field="bool" />

+			<property field="bs" />

+			<property field="ss" />

+			<property field="is" />

+			<property field="ls" />

+			<property field="ds" />

+			<property field="fs" />

+			<property field="cs" />

+			<property field="bools" />

+			<property field="string" />

+			<property field="strings" />

+		</properties>

+	</component>

+

+	<component factory="BothConfigurableCheckService"

+		className="org.apache.felix.ipojo.test.scenarios.component.ConfigurableCheckServiceProvider"

+		architecture="true">

+		<provides />

+		<properties propagation="true">

+			<property field="b" method="updateB" />

+			<property field="s" method="updateS" />

+			<property field="i" method="updateI" />

+			<property field="l" method="updateL" />

+			<property field="d" method="updateD" />

+			<property field="f" method="updateF" />

+			<property field="c" method="updateC" />

+			<property field="bool" method="updateBool" />

+			<property field="bs" method="updateBs" />

+			<property field="ss" method="updateSs" />

+			<property field="is" method="updateIs" />

+			<property field="ls" method="updateLs" />

+			<property field="ds" method="updateDs" />

+			<property field="fs" method="updateFs" />

+			<property field="cs" method="updateCs" />

+			<property field="bools" method="updateBools" />

+			<property field="string" method="updateString" />

+			<property field="strings" method="updateStrings" />

+		</properties>

+	</component>

+

+	<component factory="MethodConfigurableCheckService"

+		className="org.apache.felix.ipojo.test.scenarios.component.ConfigurableCheckServiceProvider"

+		architecture="true">

+		<provides />

+		<properties propagation="true">

+			<property method="updateB" name="b" />

+			<property method="updateS" name="s" />

+			<property method="updateI" name="i" />

+			<property method="updateL" name="l" />

+			<property method="updateD" name="d" />

+			<property method="updateF" name="f" />

+			<property method="updateC" name="c" />

+			<property method="updateBool" name="bool" />

+			<property method="updateBs" name="bs" />

+			<property method="updateSs" name="ss" />

+			<property method="updateIs" name="is" />

+			<property method="updateLs" name="ls" />

+			<property method="updateDs" name="ds" />

+			<property method="updateFs" name="fs" />

+			<property method="updateCs" name="cs" />

+			<property method="updateBools" name="bools" />

+			<property method="updateString" name="string" />

+			<property method="updateStrings" name="strings" />

+		</properties>

+	</component>

+

+	<component factory="ParentMethodConfigurableCheckService"

+		className="org.apache.felix.ipojo.test.scenarios.component.ParentConfigurableCheckServiceProvider"

+		architecture="true">

+		<provides />

+		<properties propagation="true">

+			<property method="updateB" name="b" />

+			<property method="updateS" name="s" />

+			<property method="updateI" name="i" />

+			<property method="updateL" name="l" />

+			<property method="updateD" name="d" />

+			<property method="updateF" name="f" />

+			<property method="updateC" name="c" />

+			<property method="updateBool" name="bool" />

+			<property method="updateBs" name="bs" />

+			<property method="updateSs" name="ss" />

+			<property method="updateIs" name="is" />

+			<property method="updateLs" name="ls" />

+			<property method="updateDs" name="ds" />

+			<property method="updateFs" name="fs" />

+			<property method="updateCs" name="cs" />

+			<property method="updateBools" name="bools" />

+			<property method="updateString" name="string" type="string" />

+			<property method="updateStrings" name="strings"

+				type="java.lang.String[]" />

+		</properties>

+	</component>

+

+	<!-- Handler test -->

+	<handler

+		classname="org.apache.felix.ipojo.test.handler.CheckServiceHandler"

+		name="check"

+		namespace="org.apache.felix.ipojo.test.handler.CheckServiceHandler"

+		architecture="false">

+		<controller field="isValid" />

+	</handler>

+	<component

+		className="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		factory="HandlerTester" architecture="true">

+		<cs:check />

+	</component>

+	<instance name="HandlerTest-2" component="HandlerTester">

+		<property name="csh.simple" value="Simple" />

+		<property name="csh.map">

+			<property name="a" value="a" />

+			<property name="b" value="b" />

+			<property name="c" value="c" />

+		</property>

+	</instance>

+

+	<!-- Test lifecycle controller -->

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.LifecycleControllerTest"

+		name="lcTest">

+		<provides />

+		<controller field="m_state" />

+		<properties>

+			<property name="conf" field="m_conf" method="setConf" />

+		</properties>

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.LifecycleControllerTest"

+		name="lcTest2" immediate="true" architecture="true">

+		<provides />

+		<controller field="m_state" />

+		<properties>

+			<property name="conf" field="m_conf" method="setConf" />

+		</properties>

+	</component>

+

+	<!--  Inherited Provides -->

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"

+		name="PI1" architecture="true">

+		<provides />

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"

+		name="PI1-1" architecture="true">

+		<provides

+			interface="org.apache.felix.ipojo.test.scenarios.service.ParentParentInterface" />

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation1"

+		name="PI1-2" architecture="true">

+		<provides

+			interface="{org.apache.felix.ipojo.test.scenarios.service.ParentParentInterface, org.apache.felix.ipojo.test.scenarios.service.ParentInterface2}" />

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"

+		name="PI2" architecture="true">

+		<provides />

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation2"

+		name="PI2-1" architecture="true">

+		<provides

+			interface="org.apache.felix.ipojo.test.scenarios.service.ParentParentInterface" />

+	</component>

+

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.inherited.ProcessImplementation3"

+		name="PI3" architecture="true">

+		<provides />

+	</component>

+

+	<instance component="log" name="MyLogger" />

+</ipojo>

diff --git a/ipojo/white.board.pattern.handler/metadata.xml b/ipojo/white.board.pattern.handler/metadata.xml
new file mode 100644
index 0000000..75de2bb
--- /dev/null
+++ b/ipojo/white.board.pattern.handler/metadata.xml
@@ -0,0 +1,6 @@
+<ipojo>

+	<handler

+		classname="org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler"

+		name="wbp" namespace="org.apache.felix.ipojo.white-board-pattern">

+	</handler>

+</ipojo>
\ No newline at end of file
diff --git a/ipojo/white.board.pattern.handler/pom.xml b/ipojo/white.board.pattern.handler/pom.xml
new file mode 100644
index 0000000..ccbe8ac
--- /dev/null
+++ b/ipojo/white.board.pattern.handler/pom.xml
@@ -0,0 +1,91 @@
+<!--

+	Licensed to the Apache Software Foundation (ASF) under one

+	or more contributor license agreements.  See the NOTICE file

+	distributed with this work for additional information

+	regarding copyright ownership.  The ASF licenses this file

+	to you under the Apache License, Version 2.0 (the

+	"License"); you may not use this file except in compliance

+	with the License.  You may obtain a copy of the License at

+	

+	http://www.apache.org/licenses/LICENSE-2.0

+	

+	Unless required by applicable law or agreed to in writing,

+	software distributed under the License is distributed on an

+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+	KIND, either express or implied.  See the License for the

+	specific language governing permissions and limitations

+	under the License.

+-->

+<project>

+	<parent>

+		<artifactId>iPOJO</artifactId>

+		<groupId>org.apache.felix</groupId>

+		<version>0.7.6-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<name>Apache Felix iPOJO White Board Pattern Handler</name>

+	<artifactId>

+		org.apache.felix.ipojo.handler.white.board.pattern

+	</artifactId>

+

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.metadata</artifactId>

+			<version>${pom.version}</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.core</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.osgi.compendium</artifactId>

+			<version>1.0.0</version>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Private-Package>

+							org.apache.felix.ipojo.handler.wbp

+						</Private-Package>

+						<Bundle-Name>${pom.name}</Bundle-Name>

+						<Bundle-SymbolicName>

+							ipojo.event.admin.handler.wbp

+						</Bundle-SymbolicName>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-ipojo-plugin</artifactId>

+				<version>${pom.version}</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>ipojo-bundle</goal>

+						</goals>

+						<configuration>

+							<metadata>metadata.xml</metadata>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+		</plugins>

+	</build>

+</project>

diff --git a/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java b/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java
new file mode 100644
index 0000000..d0206b5
--- /dev/null
+++ b/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardManager.java
@@ -0,0 +1,173 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.wbp;

+

+import java.lang.reflect.InvocationTargetException;

+

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.util.Callback;

+import org.apache.felix.ipojo.util.Tracker;

+import org.apache.felix.ipojo.util.TrackerCustomizer;

+import org.osgi.framework.Filter;

+import org.osgi.framework.ServiceReference;

+

+/**

+ * Manage a white board pattern.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class WhiteBoardManager implements TrackerCustomizer {

+    

+    /**

+     * monitored filter. 

+     */

+    private Filter m_filter;

+    

+    /**

+     * onArrival method. 

+     */

+    private Callback m_onArrival;

+    

+    /**

+     * onDeparture method. 

+     */

+    private Callback m_onDeparture;

+    

+    /**

+     * onModify method. 

+     */

+    private Callback m_onModification;

+    

+    /**

+     * Service Tracker. 

+     */

+    private Tracker m_tracker;

+    

+    /**

+     * Attached handler. 

+     */

+    private PrimitiveHandler m_handler;

+    

+    /**

+     * Constructor.

+     * @param handler : attached handler

+     * @param filter : monitored filter

+     * @param bind : onArrival method

+     * @param unbind : onDeparture method

+     * @param modification : onModify method

+     */

+    public WhiteBoardManager(WhiteBoardPatternHandler handler, Filter filter, String bind, String unbind, String modification) {

+        m_handler = handler;

+        m_onArrival = new Callback(bind, new Class[] {ServiceReference.class}, false, m_handler.getInstanceManager());

+        m_onDeparture = new Callback(unbind, new Class[] {ServiceReference.class}, false, m_handler.getInstanceManager());

+        if (modification != null) {

+            m_onModification = new Callback(modification, new Class[] {ServiceReference.class}, false, m_handler.getInstanceManager());

+        }

+        m_filter = filter;

+        m_tracker = new Tracker(handler.getInstanceManager().getContext(), m_filter, this);

+    }

+    

+    /**

+     * Open the tracker.

+     */

+    public void start() {

+        m_tracker.open();

+    }

+    

+    /**

+     * Close the tracker.

+     */

+    public void stop() {

+        m_tracker.close();

+    }

+

+    /**

+     * A new service was added to the tracker.

+     * @param arg0 : service reference.

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)

+     */

+    public void addedService(ServiceReference arg0) {

+        try {

+            m_onArrival.call(new Object[] {arg0});

+        } catch (NoSuchMethodException e) {

+            m_handler.error("The onArrival method " + m_onArrival.getMethod() + " does not exist in the class", e);

+            m_handler.getInstanceManager().stop();

+        } catch (IllegalAccessException e) {

+            m_handler.error("The onArrival method " + m_onArrival.getMethod() + " cannot be invoked", e);

+            m_handler.getInstanceManager().stop();

+        } catch (InvocationTargetException e) {

+            m_handler.error("The onArrival method " + m_onArrival.getMethod() + " has thrown an exception", e.getTargetException());

+            m_handler.getInstanceManager().stop();

+        }

+    }

+

+    /**

+     * A new service is detected.

+     * @param arg0 : service reference

+     * @return true to add the service

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+     */

+    public boolean addingService(ServiceReference arg0) {

+        return true;

+    }

+

+    /**

+     * An existing service was modified.

+     * @param arg0 : service reference

+     * @param arg1 : service object (if already get)

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void modifiedService(ServiceReference arg0, Object arg1) {

+        if (m_onModification != null) {

+            try {

+                m_onModification.call(new Object[] {arg0});

+            } catch (NoSuchMethodException e) {

+                m_handler.error("The onModification method " + m_onModification.getMethod() + " does not exist in the class", e);

+                m_handler.getInstanceManager().stop();

+            } catch (IllegalAccessException e) {

+                m_handler.error("The onModification method " + m_onModification.getMethod() + " cannot be invoked", e);

+                m_handler.getInstanceManager().stop();

+            } catch (InvocationTargetException e) {

+                m_handler.error("The onModification method " + m_onModification.getMethod() + " has thrown an exception", e.getTargetException());

+                m_handler.getInstanceManager().stop();

+            }

+        }

+    }

+

+    /**

+     * A service disappears.

+     * @param arg0 : service reference

+     * @param arg1 : service object (if already get)

+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)

+     */

+    public void removedService(ServiceReference arg0, Object arg1) {

+        try {

+            m_onDeparture.call(new Object[] {arg0});

+        } catch (NoSuchMethodException e) {

+            m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " does not exist in the class", e);

+            m_handler.getInstanceManager().stop();

+        } catch (IllegalAccessException e) {

+            m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " cannot be invoked", e);

+            m_handler.getInstanceManager().stop();

+        } catch (InvocationTargetException e) {

+            m_handler.error("The onDeparture method " + m_onDeparture.getMethod() + " has thrown an exception", e.getTargetException());

+            m_handler.getInstanceManager().stop();

+        }

+    }

+

+}

diff --git a/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java b/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
new file mode 100644
index 0000000..4fb735b
--- /dev/null
+++ b/ipojo/white.board.pattern.handler/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
@@ -0,0 +1,99 @@
+/* 

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.wbp;

+

+import java.util.ArrayList;

+import java.util.Dictionary;

+import java.util.List;

+

+import org.apache.felix.ipojo.ConfigurationException;

+import org.apache.felix.ipojo.PrimitiveHandler;

+import org.apache.felix.ipojo.metadata.Element;

+import org.osgi.framework.InvalidSyntaxException;

+

+/**

+ * White board pattern handler.

+ * This handler aims to automate white board patterns by invoking callback when needed.

+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

+ */

+public class WhiteBoardPatternHandler extends PrimitiveHandler {

+    

+    /**

+     * Handler namespace.

+     */

+    public static final String NAMESPACE = "org.apache.felix.ipojo.white-board-pattern";

+    

+    /**

+     * White board pattern to manage. By default just one. 

+     */

+    private List m_managers = new ArrayList(1);

+

+    /**

+     * Configure method. It will parse metadata to analyze org.apache.felix.ipojo.white-board-pattern:wbp element. 

+     * @param elem : component type description

+     * @param dict : instance description

+     * @throws ConfigurationException : occurs when the description is not valid.

+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)

+     */

+    public void configure(Element elem, Dictionary dict) throws ConfigurationException {

+        Element[] elems = elem.getElements("wbp", NAMESPACE);

+        for (int i = 0; i < elems.length; i++) {

+            String filter = elems[i].getAttribute("filter");

+            String onArrival = elems[i].getAttribute("onArrival");

+            String onDeparture = elems[i].getAttribute("onDeparture");

+            String onModification = elems[i].getAttribute("onModification");

+            

+            if (filter == null) {

+                throw new ConfigurationException("The white board pattern element requires a filter attribute");

+            }

+            if (onArrival == null || onDeparture == null) {

+                throw new ConfigurationException("The white board pattern element requires the onArrival and onDeparture attributes");

+            }

+            

+            try {

+                WhiteBoardManager wbm = new WhiteBoardManager(this, getInstanceManager().getContext().createFilter(filter), onArrival, onDeparture, onModification);

+                m_managers.add(wbm);

+            } catch (InvalidSyntaxException e) {

+                throw new ConfigurationException("The filter " + filter + " is invalid : " + e);

+            }

+        }

+        

+    }

+

+    /**

+     * Start method : start managers.

+     * @see org.apache.felix.ipojo.Handler#start()

+     */

+    public void start() {

+        for (int i = 0; i < m_managers.size(); i++) {

+            ((WhiteBoardManager) m_managers.get(i)).start();

+        }

+    }

+

+    /**

+     * Stop method : stop managers.

+     * @see org.apache.felix.ipojo.Handler#stop()

+     */

+    public void stop() {

+        for (int i = 0; i < m_managers.size(); i++) {

+            ((WhiteBoardManager) m_managers.get(i)).stop();

+        } 

+    }

+

+}