Fix FELIX-4040, reimplement configuration admin support

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1477027 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/pom.xml b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/pom.xml
new file mode 100644
index 0000000..bb52beb
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT 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>org.apache.felix.ipojo.runtime.core-it</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ipojo-core-configuration-admin-test</artifactId>
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configadmin</artifactId>
+            <version>1.2.8</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ConfigurableFooProvider.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ConfigurableFooProvider.java
new file mode 100644
index 0000000..f0df68f
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ConfigurableFooProvider.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.runtime.core.components;
+
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+
+import java.util.Properties;
+
+public class ConfigurableFooProvider implements FooService {
+
+    private String message; // Configurable property
+    private int invokeCount = 0;
+
+    public void setMessage(String message) {
+        System.err.println("=== Set message to " + message);
+        this.message = message;
+        invokeCount++;
+    }
+
+    public boolean foo() {
+        return true;
+    }
+
+    public Properties fooProps() {
+        Properties props = new Properties();
+        if (message == null) {
+            props.put("message", "NULL");
+        } else {
+            props.put("message", message);
+        }
+        props.put("count", new Integer(invokeCount));
+        return props;
+    }
+
+    public boolean getBoolean() {
+        return false;
+    }
+
+    public double getDouble() {
+        return invokeCount;
+    }
+
+    public int getInt() {
+        return invokeCount;
+    }
+
+    public long getLong() {
+        return invokeCount;
+    }
+
+    public Boolean getObject() {
+        return null;
+    }
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/CheckService.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/CheckService.java
new file mode 100644
index 0000000..c3d38ec
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/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.runtime.core.services;

+

+import java.util.Properties;

+

+public interface CheckService {

+    

+    public static final String foo = "foo";

+	

+	public boolean check();

+	

+	public Properties getProps();

+

+}

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/FooService.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/FooService.java
new file mode 100644
index 0000000..716115f
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/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.runtime.core.services;

+

+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/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/resources/metadata.xml b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/resources/metadata.xml
new file mode 100644
index 0000000..6affd5b
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/main/resources/metadata.xml
@@ -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.

+  -->

+

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

+       xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"

+       xmlns="org.apache.felix.ipojo">

+    <component classname="org.apache.felix.ipojo.runtime.core.components.ConfigurableFooProvider"

+               name="CA-ConfigurableProvider">

+        <provides/>

+        <properties>

+            <property name="message" method="setMessage"/>

+        </properties>

+    </component>

+

+    <component classname="org.apache.felix.ipojo.runtime.core.components.ConfigurableFooProvider"

+               immediate="true"

+               name="CA-ImmConfigurableProvider">

+        <provides/>

+        <properties>

+            <property name="message" method="setMessage"/>

+        </properties>

+    </component>

+

+

+</ipojo>

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
new file mode 100644
index 0000000..551970a
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.felix.ipojo.runtime.core.components.*;
+import org.apache.felix.ipojo.runtime.core.services.CheckService;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.options.CompositeOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.ow2.chameleon.testing.helpers.IPOJOHelper;
+import org.ow2.chameleon.testing.helpers.OSGiHelper;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.*;
+
+/**
+ * Bootstrap the test from this project
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class Common {
+
+    public static long UPDATE_WAIT_TIME = 2000;
+
+    @Inject
+    BundleContext bc;
+
+    OSGiHelper osgiHelper;
+    IPOJOHelper ipojoHelper;
+
+    @Configuration
+    public Option[] config() throws MalformedURLException {
+        Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+        root.setLevel(Level.INFO);
+
+        return options(
+                ipojoBundles(),
+                junitBundles(),
+                testedBundle(),
+                systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("WARN")
+        );
+    }
+
+    @Before
+    public void commonSetUp() {
+        osgiHelper = new OSGiHelper(bc);
+        ipojoHelper = new IPOJOHelper(bc);
+
+        // Dump OSGi Framework information
+        String vendor = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_VENDOR);
+        if (vendor == null) {
+            vendor = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_SYMBOLICNAME);
+        }
+        String version = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_VERSION);
+        System.out.println("OSGi Framework : " + vendor + " - " + version);
+
+        waitForStability(bc);
+    }
+
+    public Bundle getTestBundle() {
+        return osgiHelper.getBundle("test.bundle");
+    }
+
+    @After
+    public void commonTearDown() {
+        ipojoHelper.dispose();
+        osgiHelper.dispose();
+    }
+
+    public CompositeOption ipojoBundles() {
+        return new DefaultCompositeOption(
+                mavenBundle("org.apache.felix", "org.apache.felix.ipojo").versionAsInProject(),
+                mavenBundle("org.ow2.chameleon.testing", "osgi-helpers").versionAsInProject(),
+                mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject());
+    }
+
+    public Option testedBundle() throws MalformedURLException {
+        File out = new File("target/tested/bundle.jar");
+
+        TinyBundle tested = TinyBundles.bundle();
+
+        // We look inside target/classes to find the class and resources
+        File classes = new File("target/classes");
+        Collection<File> files = FileUtils.listFilesAndDirs(classes, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
+        List<File> services = new ArrayList<File>();
+        for (File file : files) {
+            if (file.isDirectory()) {
+                // By convention we export of .services and .service package
+                if (file.getName().endsWith("services")  || file.getName().endsWith("service")) {
+                    services.add(file);
+                }
+            } else {
+                // We need to compute the path
+                String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1);
+                tested.add(path, file.toURI().toURL());
+                System.out.println(file.getName() + " added to " + path);
+            }
+        }
+
+        String export = "";
+        for (File file : services) {
+            if (export.length() > 0) { export += ", "; }
+            String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1);
+            String packageName = path.replace('/', '.');
+            export += packageName;
+        }
+
+        System.out.println("Exported packages : " + export);
+
+        InputStream inputStream = tested
+                .set(Constants.BUNDLE_SYMBOLICNAME, "test.bundle")
+                .set(Constants.IMPORT_PACKAGE, "*")
+                .set(Constants.EXPORT_PACKAGE, export)
+                .build(IPOJOStrategy.withiPOJO(new File("src/main/resources")));
+
+        try {
+            org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, out);
+            return bundle(out.toURI().toURL().toExternalForm());
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Cannot compute the url of the manipulated bundle");
+        } catch (IOException e) {
+            throw new RuntimeException("Cannot write of the manipulated bundle");
+        }
+    }
+
+    /**
+     * Waits for stability:
+     * <ul>
+     * <li>all bundles are activated
+     * <li>service count is stable
+     * </ul>
+     * If the stability can't be reached after a specified time,
+     * the method throws a {@link IllegalStateException}.
+     *
+     * @param context the bundle context
+     * @throws IllegalStateException when the stability can't be reach after a several attempts.
+     */
+    private void waitForStability(BundleContext context) throws IllegalStateException {
+        // Wait for bundle initialization.
+        boolean bundleStability = getBundleStability(context);
+        int count = 0;
+        while (!bundleStability && count < 500) {
+            try {
+                Thread.sleep(5);
+            } catch (InterruptedException e) {
+                // Interrupted
+            }
+            count++;
+            bundleStability = getBundleStability(context);
+        }
+
+        if (count == 500) {
+            System.err.println("Bundle stability isn't reached after 500 tries");
+            throw new IllegalStateException("Cannot reach the bundle stability");
+        }
+
+        boolean serviceStability = false;
+        count = 0;
+        int count1 = 0;
+        int count2 = 0;
+        while (!serviceStability && count < 500) {
+            try {
+                ServiceReference[] refs = context.getServiceReferences((String) null, null);
+                count1 = refs.length;
+                Thread.sleep(500);
+                refs = context.getServiceReferences((String) null, null);
+                count2 = refs.length;
+                serviceStability = count1 == count2;
+            } catch (Exception e) {
+                System.err.println(e);
+                serviceStability = false;
+                // Nothing to do, while recheck the condition
+            }
+            count++;
+        }
+
+        if (count == 500) {
+            System.err.println("Service stability isn't reached after 500 tries (" + count1 + " != " + count2);
+            throw new IllegalStateException("Cannot reach the service stability");
+        }
+    }
+
+    /**
+     * Are bundle stables.
+     *
+     * @param bc the bundle context
+     * @return <code>true</code> if every bundles are activated.
+     */
+    private boolean getBundleStability(BundleContext bc) {
+        boolean stability = true;
+        Bundle[] bundles = bc.getBundles();
+        for (Bundle bundle : bundles) {
+            stability = stability && (bundle.getState() == Bundle.ACTIVE);
+        }
+        return stability;
+    }
+
+    public boolean isKF() {
+        return bc.getClass().toString().contains("knopflerfish");
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/ConfigurationMonitor.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/ConfigurationMonitor.java
new file mode 100644
index 0000000..8f761cb
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/ConfigurationMonitor.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import junit.framework.Assert;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+
+public class ConfigurationMonitor implements ConfigurationListener {
+    
+    private String waitForEvent;
+    private boolean detected;
+    private ServiceRegistration reg;
+
+    public synchronized void configurationEvent(ConfigurationEvent arg0) {
+        System.out.println(arg0.getPid() + " reconfiguration received");
+        if (waitForEvent != null) {
+            if (arg0.getPid().equals(waitForEvent)) {
+                this.detected = true;
+            }
+        }
+    }
+    
+    public ConfigurationMonitor(BundleContext bc) {
+        reg = bc.registerService(ConfigurationListener.class.getName(), this, null);
+    }
+    
+    public void stop() {
+        reg.unregister();
+        reg = null;
+    }
+    
+    public void waitForEvent(String pid, String mes) {
+        waitForEvent = pid;
+        detected = false;
+        long begin = System.currentTimeMillis();
+        long duration = 0;
+        while( ! this.detected) {
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                // Interrupted
+            }
+            long end = System.currentTimeMillis();
+            duration = end - begin;
+            if (duration > 10000) {
+                Assert.fail(mes + " -> Timeout when waiting for a reconfiguration of " + pid);
+            }
+        }
+        System.out.println("Reconfiguration detected of " + pid);
+        waitForEvent = null;
+        detected = false;
+    }
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForImmediate.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForImmediate.java
new file mode 100644
index 0000000..72097b1
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForImmediate.java
@@ -0,0 +1,404 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.*;
+
+public class TestManagedServiceFactoryTestForImmediate extends Common {
+
+    private ComponentFactory factory;
+    private ConfigurationAdmin admin;
+
+    @Before
+    public void setUp() {
+        factory = (ComponentFactory) ipojoHelper.getFactory("CA-ImmConfigurableProvider");
+        admin = (ConfigurationAdmin) osgiHelper.getServiceObject(ConfigurationAdmin.class.getName(), null);
+        assertNotNull("Check configuration admin availability", admin);
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ImmConfigurableProvider)");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    @After
+    public void tearDown() {
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ImmConfigurableProvider)");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+        admin = null;
+
+
+    }
+
+    @Test
+    public void testCreationAndReconfiguration() {
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 2, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testCreationAndReconfiguration2() {
+        //The reconfiguration happens before the service invocation
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+        System.out.println("PID : " + pid);
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Check object -2", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        //Invoke
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = ((Integer) p.get("count")).intValue();
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 2, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testDelayedCreationAndReconfiguration() {
+        factory.stop();
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        assertNull("check no instance", osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")"));
+
+        factory.start();
+
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        //assertEquals("Assert count", 2, count);
+        // This test was removed as the result can be 3. 
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testDelayedCreationAndReconfiguration2() {
+        factory.stop();
+        //The reconfiguration happens before the service invocation
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        assertNull("check no instance", osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")"));
+
+        factory.start();
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Check object -1", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        //Invoke
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 2, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForServices.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForServices.java
new file mode 100644
index 0000000..b2cb1c5
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceFactoryTestForServices.java
@@ -0,0 +1,406 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.*;
+
+public class TestManagedServiceFactoryTestForServices extends Common {
+
+    private ComponentFactory factory;
+    private ConfigurationAdmin admin;
+
+    @Before
+    public void setUp() {
+        factory = (ComponentFactory) ipojoHelper.getFactory("CA-ConfigurableProvider");
+        admin = (ConfigurationAdmin) osgiHelper.getServiceObject(ConfigurationAdmin.class.getName(), null);
+        assertNotNull("Check configuration admin availability", admin);
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ConfigurableProvider)");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @After
+    public void tearDown() {
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ConfigurableProvider)");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+        admin = null;
+
+
+    }
+
+    @Test
+    public void testMSFCreationAndReconfiguration() {
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+        System.out.println("PID : " + pid);
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        osgiHelper.waitForService(FooService.class.getName(), "(instance.name=" + pid + ")", 1000);
+
+        ServiceReference refx = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNotNull("Check refx", refx);
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNotNull("Check fs", fs);
+
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+
+        Dictionary p2 = configuration.getProperties();
+        p2.put("message", "message2");
+        try {
+            System.err.println("The configuration will be updated with message2");
+
+            configuration.update(p2);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        System.err.println("The configuration should be updated with message2");
+
+        fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 2, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testMSFCreationAndReconfiguration2() {
+        //The reconfiguration happens before the service invocation
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Check no object -2", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        //Invoke
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testDelayedCreationAndReconfiguration() {
+        factory.stop();
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+
+        assertNull("check no instance", osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")"));
+
+        factory.start();
+
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        osgiHelper.waitForService(FooService.class.getName(), "(instance.name=" + pid + ")", 1000);
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        System.out.println("===");
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        System.out.println("===");
+
+        fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 2, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+    @Test
+    public void testDelayedCreationAndReconfiguration2() {
+        factory.stop();
+        //The reconfiguration happens before the service invocation
+        Configuration configuration = null;
+        try {
+            configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", "?");
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+        Dictionary props = configuration.getProperties();
+        if (props == null) {
+            props = new Properties();
+        }
+        props.put("message", "message");
+
+        try {
+            configuration.update(props);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        String pid = configuration.getPid();
+        System.out.println("PID : " + pid);
+
+        assertNull("check no instance", osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")"));
+
+        factory.start();
+
+
+        //  The instance should be created, wait for the architecture service
+        osgiHelper.waitForService(Architecture.class.getName(), "(architecture.instance=" + pid + ")", 1000);
+        Architecture architecture = (Architecture) osgiHelper.getServiceObject(Architecture.class.getName(), "(architecture.instance=" + pid + ")");
+
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        // Wait for the processing of the first configuration.
+        try {
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (InterruptedException e1) {
+            fail(e1.getMessage());
+        }
+
+        props.put("message", "message2");
+        try {
+            configuration.update(props);
+            // Update the configuration ...
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        //architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Check no object -2", 0, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        //Invoke
+        FooService fs = (FooService) osgiHelper.getServiceObject(FooService.class.getName(), "(instance.name=" + pid + ")");
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        // architecture = (Architecture) osgiHelper.getServiceObject( Architecture.class.getName(), "(architecture.instance="+pid+")");
+
+        assertEquals("Assert Message", "message2", mes);
+        assertEquals("Assert count", 1, count);
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) architecture.getInstanceDescription()).getCreatedObjects().length);
+
+        try {
+            configuration.delete();
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = osgiHelper.getServiceReference(FooService.class.getName(), "(instance.name=" + pid + ")");
+        assertNull("Check unavailability", ref);
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForImmediate.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForImmediate.java
new file mode 100644
index 0000000..c116ab1
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForImmediate.java
@@ -0,0 +1,398 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class TestManagedServiceTestForImmediate extends Common {
+
+    private String factNameImm = "CA-ImmConfigurableProvider";
+    private String msp = "foo";
+
+    private ComponentFactory factImm;
+
+    private ConfigurationAdmin admin;
+
+    ConfigurationMonitor listener;
+
+    @Before
+    public void setUp() throws InterruptedException {
+        factImm = (ComponentFactory) ipojoHelper.getFactory(factNameImm);
+        admin = (ConfigurationAdmin) osgiHelper.getServiceObject(ConfigurationAdmin.class.getName(), null);
+        assertNotNull("Check configuration admin availability", admin);
+        cleanConfigurationAdmin();
+        listener = new ConfigurationMonitor(bc);
+    }
+
+    @After
+    public void tearDown() {
+        listener.stop();
+        cleanConfigurationAdmin();
+        admin = null;
+    }
+
+    private void cleanConfigurationAdmin() {
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.pid=" + msp + ")");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testFactoryCreationAndReconfigurationUsingManagedService() {
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp); // Exposes a ManagedService.
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factImm.createComponentInstance(props);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message", mes);
+        assertEquals("Check count", 1, count);
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            System.err.println("updated ? ");
+            //Thread.sleep(UPDATE_WAIT_TIME);
+            listener.waitForEvent(configuration.getPid(), "1");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message2", mes);
+        assertEquals("Check count", 2, count);
+
+        instance.dispose();
+        cleanConfigurationAdmin();
+    }
+
+    /**
+     * Creates an instance using a factory configuration.
+     * The configuration specifies the managed.service.pid property
+     * Reconfiguration is applied using the exposed managed service.
+     */
+    @Test
+    public void testCreationUsingFactoryConfigurationSettingTheManagedServicePid() {
+        Configuration conf = null;
+        try {
+            //TODO test multi-location:?
+            conf = admin.createFactoryConfiguration(factNameImm, getTestBundle().getLocation());
+            Dictionary props = conf.getProperties();
+            if (props == null) {
+                props = new Properties();
+            }
+            props.put("managed.service.pid", msp);
+            props.put("message", "message");
+            conf.update(props);
+            Thread.sleep(UPDATE_WAIT_TIME); // Wait for the creation.
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+
+        Architecture arch = (Architecture) osgiHelper.getServiceObject(org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), conf.getPid());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        // arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message", mes);
+        assertEquals("Check count", 1, count);
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            //Thread.sleep(UPDATE_WAIT_TIME);
+            listener.waitForEvent(configuration.getPid(), "1");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        //  arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), conf.getPid());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        // arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        if (mes.equals("message")) {
+            System.out.println("Warning, configuration not yet applied");
+            assertEquals("Check count - W", 1, count);
+        } else {
+            assertEquals("Check message", "message2", mes);
+            assertEquals("Check count", 2, count);
+        }
+
+        try {
+            conf.delete();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+    }
+
+    @Test
+    public void testCreationAndReconfiguration2() {
+        // The configuration exists before the instance creation.
+
+        //Update
+        Configuration configuration = null;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factImm.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        //  int count1 = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message - 1 (" + mes + ")", "message2", mes); // Already reconfigured.
+        // assertEquals("Check count", 2, count); // Two : 1) "message" on immediate, "message2" on the reconfiguration,
+        // not necessary as the property can be set before the immediate instance creation
+
+        instance.dispose();
+
+        //Reconfiguration
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message3");
+            configuration.update(prc);
+            listener.waitForEvent(msp, "1");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        // Recreation of the instance.
+        props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        instance = null;
+        try {
+            instance = factImm.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME * 2);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        // int count = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message already reconfigured", "message3", mes); // Already reconfigured.
+        //assertEquals("Check count", count1 + 1, count); // message before the reconfiguration, message3 after the reconfiguration
+
+        instance.dispose();
+
+
+    }
+
+    @Test
+    public void testCreationAndReconfiguration3() {
+        // The configuration exists before the instance creation.
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            listener.waitForEvent(msp, "1");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factImm.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        // int count = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message2", mes); // Already reconfigured.
+        //assertEquals("Check count", 1, count);
+
+        //Reconfiguration
+        try {
+            configuration = admin.getConfiguration(msp);
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message3");
+            configuration.update(prc);
+            //Thread.sleep(UPDATE_WAIT_TIME);
+            listener.waitForEvent(msp, "1");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        instance.dispose();
+
+        // Recreation of the instance.
+        props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        instance = null;
+        try {
+            instance = factImm.createComponentInstance(props);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        //  count = ((Integer) p.get("count")).intValue();
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message3", mes); // Already reconfigured.
+        // assertEquals("Check count", 1, count);
+
+        instance.dispose();
+
+
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForService.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForService.java
new file mode 100644
index 0000000..68eb29d
--- /dev/null
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-admin-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManagedServiceTestForService.java
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class TestManagedServiceTestForService extends Common {
+
+    private String factNameSvc = "CA-ConfigurableProvider";
+    private String msp = "foo";
+
+    private ComponentFactory factSvc;
+
+    private ConfigurationAdmin admin;
+
+    ConfigurationMonitor listener;
+
+    @Before
+    public void setUp() {
+        factSvc = (ComponentFactory) ipojoHelper.getFactory(factNameSvc);
+        admin = (ConfigurationAdmin) osgiHelper.getServiceObject(ConfigurationAdmin.class.getName(), null);
+        assertNotNull("Check configuration admin availability", admin);
+        cleanConfigurationAdmin();
+        listener = new ConfigurationMonitor(bc);
+    }
+
+    @After
+    public void tearDown() {
+        listener.stop();
+        cleanConfigurationAdmin();
+        admin = null;
+    }
+
+    private void cleanConfigurationAdmin() {
+        try {
+            Configuration[] configurations = admin.listConfigurations("(service.pid=" + msp + ")");
+            for (int i = 0; configurations != null && i < configurations.length; i++) {
+                configurations[i].delete();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testCreationUsingFactoryAndReconfigurationUsingManagedService() {
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factSvc.createComponentInstance(props);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message", mes);
+        assertEquals("Check count", 1, count);
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        if (mes.equals("message")) {
+            System.out.println("Warning, configuration not yet applied");
+            assertEquals("Check count - W", 1, count);
+        } else {
+            assertEquals("Check message", "message2", mes);
+            assertEquals("Check count", 2, count);
+        }
+
+        instance.dispose();
+
+    }
+
+    @Test
+    public void testCreationUsingMSFAndReconfigurationUsingManagedService() {
+        Configuration conf = null;
+        try {
+            conf = admin.createFactoryConfiguration(factNameSvc, getTestBundle().getLocation());
+            Dictionary props = conf.getProperties();
+            if (props == null) {
+                props = new Properties();
+            }
+            props.put("managed.service.pid", msp);
+            props.put("message", "message");
+            conf.update(props);
+            Thread.sleep(UPDATE_WAIT_TIME); // Wait for the creation.
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        Architecture arch = (Architecture) osgiHelper.getServiceObject(org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), conf.getPid());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        // arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message", mes);
+        assertEquals("Check count", 1, count);
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        // arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), conf.getPid());
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        // arch = (Architecture) osgiHelper.getServiceObject( org.apache.felix.ipojo.architecture.Architecture.class.getName(), "(architecture.instance=" + conf.getPid() + ")");
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) arch.getInstanceDescription()).getCreatedObjects().length);
+        if (mes.equals("message")) {
+            System.out.println("Warning, configuration not yet applied");
+            assertEquals("Check count - W", 1, count);
+        } else {
+            assertEquals("Check message", "message2", mes);
+            assertEquals("Check count", 2, count);
+        }
+
+        try {
+            conf.delete();
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+    }
+
+    @Test
+    public void testConfigurationPushedBeforeInstantiationUsingFactory() {
+        // The configuration exists before the instance creation.
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            //listener.waitForEvent(msp, "1");
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factSvc.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message2", mes); // Already reconfigured.
+        assertEquals("Check count", 1, count);
+
+        instance.dispose();
+
+        //Reconfiguration
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message3");
+            configuration.update(prc);
+            listener.waitForEvent(msp, "2");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        // Recreation of the instance.
+        props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        instance = null;
+        try {
+            instance = factSvc.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message3", mes); // Already reconfigured.
+        assertEquals("Check count", 1, count);
+
+        instance.dispose();
+
+
+    }
+
+    @Test
+    public void testConfigurationPushedBeforeInstantiationUsingFactoryAndReconfiguration() {
+        // The configuration exists before the instance creation.
+
+        //Update
+        Configuration configuration;
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message2");
+            configuration.update(prc);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        Properties props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        ComponentInstance instance = null;
+        try {
+            instance = factSvc.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        FooService fs = (FooService) bc.getService(ref);
+        Properties p = fs.fooProps();
+        String mes = p.getProperty("message");
+        int count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message2", mes); // Already reconfigured.
+        assertEquals("Check count", 1, count);
+
+        //Reconfiguration
+        try {
+            configuration = admin.getConfiguration(msp, getTestBundle().getLocation());
+            Dictionary prc = configuration.getProperties();
+            if (prc == null) {
+                prc = new Properties();
+            }
+            prc.put("message", "message3");
+            configuration.update(prc);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        instance.dispose();
+
+        // Recreation of the instance.
+        props = new Properties();
+        props.put("managed.service.pid", msp);
+        props.put("message", "message");
+        instance = null;
+        try {
+            instance = factSvc.createComponentInstance(props);
+            Thread.sleep(UPDATE_WAIT_TIME);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+        ref = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());
+        assertEquals("Check no object", 0, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertNotNull("FS availability", ref);
+
+        fs = (FooService) bc.getService(ref);
+        p = fs.fooProps();
+        mes = p.getProperty("message");
+        count = (Integer) p.get("count");
+        assertEquals("Check 1 object", 1, ((PrimitiveInstanceDescription) instance.getInstanceDescription()).getCreatedObjects().length);
+        assertEquals("Check message", "message3", mes); // Already reconfigured.
+        assertEquals("Check count", 1, count);
+
+        instance.dispose();
+
+
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
index f0fe02f..a39d105 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/Common.java
@@ -109,7 +109,12 @@
     public CompositeOption ipojoBundles() {
         return new DefaultCompositeOption(
                 mavenBundle("org.apache.felix", "org.apache.felix.ipojo").versionAsInProject(),
-                mavenBundle("org.ow2.chameleon.testing", "osgi-helpers").versionAsInProject());
+                mavenBundle("org.ow2.chameleon.testing", "osgi-helpers").versionAsInProject(),
+                mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject());
+    }
+
+    public Bundle getTestBundle() {
+        return osgiHelper.getBundle("test.bundle");
     }
 
     public Option testedBundle() throws MalformedURLException {
diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurableProperties.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurablePropertiesUsingConfigAdmin.java
similarity index 74%
rename from ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurableProperties.java
rename to ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurablePropertiesUsingConfigAdmin.java
index f00c1f8..84ebf4a 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurableProperties.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestDynamicallyConfigurablePropertiesUsingConfigAdmin.java
@@ -23,10 +23,16 @@
 import org.junit.After;

 import org.junit.Before;

 import org.junit.Test;

+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;

+import org.ops4j.pax.exam.spi.reactors.PerClass;

+import org.ops4j.pax.exam.spi.reactors.PerMethod;

 import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.Configuration;

+import org.osgi.service.cm.ConfigurationAdmin;

 import org.osgi.service.cm.ConfigurationException;

 import org.osgi.service.cm.ManagedServiceFactory;

 

+import java.io.IOException;

 import java.util.Hashtable;

 import java.util.Properties;

 

@@ -34,7 +40,12 @@
 import static org.junit.Assert.assertNotNull;

 import static org.junit.Assert.fail;

 

-public class TestDynamicallyConfigurableProperties extends Common {

+/**

+ * iPOJO does not expose the ManagedServiceFactory anymore, we must use the configuration admin.

+ * To avoid conflicts with persisted configuration, we run one framework per tests

+ */

+@ExamReactorStrategy(PerMethod.class)

+public class TestDynamicallyConfigurablePropertiesUsingConfigAdmin extends Common {

 

     ComponentInstance instance, instance2;

 

@@ -64,7 +75,7 @@
     }

 

     @Test

-    public void testStatic() {

+    public void testStatic() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

         String fooP = (String) fooRef.getProperty("foo");

@@ -74,21 +85,23 @@
         assertEquals("Check bar equality -1", barP, new Integer(2));

         assertEquals("Check baz equality -1", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+        conf.put("instance.name", instance.getInstanceName());

+

+        configuration.update(conf);

+

+        // Asynchronous dispatching of the configuration

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -98,12 +111,11 @@
         assertEquals("Check foo equality -2", fooP, "foo");

         assertEquals("Check bar equality -2", barP, new Integer(2));

         assertEquals("Check baz equality -2", bazP, "zab");

-        osgiHelper.getContext().ungetService(msRef);

     }

 

 

     @Test

-    public void testStaticNoValue() {

+    public void testStaticNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

         Object fooP = fooRef.getProperty("foo");

@@ -113,21 +125,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -137,11 +149,10 @@
         assertEquals("Check foo equality -2", fooP, "foo");

         assertEquals("Check bar equality -2", barP, new Integer(2));

         assertEquals("Check baz equality -2", bazP, "zab");

-        osgiHelper.getContext().ungetService(msRef);

     }

 

     @Test

-    public void testDynamic() {

+    public void testDynamic() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -153,20 +164,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -188,11 +200,10 @@
         assertEquals("Check bar field equality", barP, new Integer(0));

 

         osgiHelper.getContext().ungetService(fooRef);

-        osgiHelper.getContext().ungetService(msRef);

     }

 

     @Test

-    public void testDynamicNoValue() {

+    public void testDynamicNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -203,20 +214,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -238,12 +250,12 @@
         assertEquals("Check bar field equality", barP, new Integer(0));

 

         osgiHelper.getContext().ungetService(fooRef);

-        osgiHelper.getContext().ungetService(msRef);

     }

 

     @Test

-    public void testDynamicString() {

-        ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

+    public void testDynamicString() throws IOException, InterruptedException {

+        ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(),

+                instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

         String fooP = (String) fooRef.getProperty("foo");

@@ -254,20 +266,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", "0");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -289,11 +302,10 @@
         assertEquals("Check bar field equality", barP, new Integer(0));

 

         osgiHelper.getContext().ungetService(fooRef);

-        osgiHelper.getContext().ungetService(msRef);

     }

 

     @Test

-    public void testPropagation() {

+    public void testPropagation() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -305,8 +317,11 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

@@ -315,12 +330,10 @@
         conf.put("bar", new Integer(2));

         conf.put("propagated1", "propagated");

         conf.put("propagated2", new Integer(1));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -337,12 +350,10 @@
         assertEquals("Check baz equality", bazP, "zab");

         assertEquals("Check propagated1 equality", prop1, "propagated");

         assertEquals("Check propagated2 equality", prop2, new Integer(1));

-

-        osgiHelper.getContext().ungetService(msRef);

     }

 

     @Test

-    public void testPropagationNoValue() {

+    public void testPropagationNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -353,8 +364,11 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

@@ -363,12 +377,10 @@
         conf.put("bar", new Integer(2));

         conf.put("propagated1", "propagated");

         conf.put("propagated2", new Integer(1));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getContext().getService(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -385,8 +397,6 @@
         assertEquals("Check baz equality", bazP, "zab");

         assertEquals("Check propagated1 equality", prop1, "propagated");

         assertEquals("Check propagated2 equality", prop2, new Integer(1));

-

-        osgiHelper.getContext().ungetService(msRef);

     }

 

 }

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndManagedServiceFactory.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndConfigAdmin.java
similarity index 79%
rename from ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndManagedServiceFactory.java
rename to ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndConfigAdmin.java
index 3bcb886..b0e3d0e 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndManagedServiceFactory.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedMethodAndConfigAdmin.java
@@ -24,12 +24,17 @@
 import org.junit.After;

 import org.junit.Before;

 import org.junit.Test;

+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;

+import org.ops4j.pax.exam.spi.reactors.PerMethod;

 import org.osgi.framework.ServiceReference;

+import org.osgi.service.cm.Configuration;

+import org.osgi.service.cm.ConfigurationAdmin;

 import org.osgi.service.cm.ConfigurationException;

 import org.osgi.service.cm.ManagedServiceFactory;

 import org.ow2.chameleon.testing.helpers.IPOJOHelper;

 import org.ow2.chameleon.testing.helpers.OSGiHelper;

 

+import java.io.IOException;

 import java.util.Dictionary;

 import java.util.Hashtable;

 import java.util.Properties;

@@ -37,14 +42,11 @@
 import static junit.framework.Assert.*;

 

 

-public class TestUpdatedMethodAndManagedServiceFactory extends Common {

-

-

+@ExamReactorStrategy(PerMethod.class)

+public class TestUpdatedMethodAndConfigAdmin extends Common {

 

     ComponentInstance instance, instance2;

 

-

-

     @Before

     public void setUp() {

         osgiHelper = new OSGiHelper(bc);

@@ -74,7 +76,7 @@
     }

 

     @Test

-    public void testStatic() {

+    public void testStatic() throws IOException, InterruptedException {

 

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

@@ -85,21 +87,21 @@
         assertEquals("Check bar equality -1", barP, new Integer(2));

         assertEquals("Check baz equality -1", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -121,7 +123,7 @@
     }

 

     @Test

-    public void testStaticNoValue() {

+    public void testStaticNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

         Object fooP = fooRef.getProperty("foo");

@@ -131,21 +133,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -166,7 +168,7 @@
     }

 

     @Test

-    public void testDynamic() {

+    public void testDynamic() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -178,20 +180,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -220,7 +223,7 @@
     }

 

     @Test

-    public void testDynamicNoValue() {

+    public void testDynamicNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -231,20 +234,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -275,7 +279,7 @@
 

 

     @Test

-    public void testDynamicString() {

+    public void testDynamicString() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -287,20 +291,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", "0");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

diff --git a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndManagedServiceFactory.java b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndConfigAdmin.java
similarity index 77%
rename from ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndManagedServiceFactory.java
rename to ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndConfigAdmin.java
index 642f0bf..dcb4d12 100644
--- a/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndManagedServiceFactory.java
+++ b/ipojo/runtime/core-it/src/it/ipojo-core-configuration-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestUpdatedNoArgMethodAndConfigAdmin.java
@@ -24,19 +24,24 @@
 import org.junit.After;

 import org.junit.Before;

 import org.junit.Test;

+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;

+import org.ops4j.pax.exam.spi.reactors.PerMethod;

 import org.osgi.framework.ServiceReference;

-import org.osgi.service.cm.ConfigurationException;

-import org.osgi.service.cm.ManagedServiceFactory;

+import org.osgi.service.cm.Configuration;

+import org.osgi.service.cm.ConfigurationAdmin;

 import org.ow2.chameleon.testing.helpers.IPOJOHelper;

 import org.ow2.chameleon.testing.helpers.OSGiHelper;

 

+import java.io.IOException;

 import java.util.Hashtable;

 import java.util.Properties;

 

-import static org.junit.Assert.*;

+import static junit.framework.Assert.assertNotNull;

+import static org.junit.Assert.assertEquals;

 

 

-public class TestUpdatedNoArgMethodAndManagedServiceFactory extends Common {

+@ExamReactorStrategy(PerMethod.class)

+public class TestUpdatedNoArgMethodAndConfigAdmin extends Common {

 

 

 

@@ -72,7 +77,7 @@
     }

 

     @Test

-    public void testStatic() {

+    public void testStatic() throws IOException, InterruptedException {

 

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

@@ -83,21 +88,21 @@
         assertEquals("Check bar equality -1", barP, new Integer(2));

         assertEquals("Check baz equality -1", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -117,7 +122,7 @@
     }

 

     @Test

-    public void testStaticNoValue() {

+    public void testStaticNoValue() throws InterruptedException, IOException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

         Object fooP = fooRef.getProperty("foo");

@@ -127,21 +132,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

 

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("bar", new Integer(2));

         conf.put("foo", "foo");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -160,7 +165,7 @@
     }

 

     @Test

-    public void testDynamic() {

+    public void testDynamic() throws InterruptedException, IOException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -172,20 +177,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

@@ -212,7 +218,7 @@
     }

 

     @Test

-    public void testDynamicNoValue() {

+    public void testDynamicNoValue() throws IOException, InterruptedException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -223,20 +229,21 @@
         assertEquals("Check bar equality -1", barP, null);

         assertEquals("Check baz equality -1", bazP, null);

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance2.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", new Integer(0));

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance2.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance2.getInstanceName());

@@ -264,7 +271,7 @@
 

 

     @Test

-    public void testDynamicString() {

+    public void testDynamicString() throws InterruptedException, IOException {

         ServiceReference fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

         assertNotNull("Check FS availability", fooRef);

 

@@ -276,20 +283,21 @@
         assertEquals("Check bar equality", barP, new Integer(2));

         assertEquals("Check baz equality", bazP, "baz");

 

-        ServiceReference msRef = ipojoHelper.getServiceReferenceByName(ManagedServiceFactory.class.getName(), instance.getFactory().getName());

-        assertNotNull("Check ManagedServiceFactory availability", msRef);

+        ConfigurationAdmin admin = osgiHelper.getServiceObject(ConfigurationAdmin.class);

+        assertNotNull("Check Configuration Admin availability", admin);

+

+        Configuration configuration = admin.getConfiguration(instance.getInstanceName(),

+                getTestBundle().getLocation());

 

         // Configuration of baz

         Properties conf = new Properties();

         conf.put("baz", "zab");

         conf.put("foo", "oof");

         conf.put("bar", "0");

-        ManagedServiceFactory ms = (ManagedServiceFactory) osgiHelper.getServiceObject(msRef);

-        try {

-            ms.updated(instance.getInstanceName(), conf);

-        } catch (ConfigurationException e) {

-            fail("Configuration Exception : " + e);

-        }

+

+        // Asynchronous dispatching of the configuration

+        configuration.update(conf);

+        Thread.sleep(200);

 

         // Recheck props

         fooRef = ipojoHelper.getServiceReferenceByName(FooService.class.getName(), instance.getInstanceName());

diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 12e99ba..cf7199d 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -32,15 +32,13 @@
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 
-import java.net.URL;
 import java.security.ProtectionDomain;
 import java.util.*;
 
 /**
  * The component factory manages component instance objects. This management
  * consists to create and manage component instances build with the current
- * component factory. This class could export Factory and ManagedServiceFactory
- * services.
+ * component factory. If the factory is public a {@see Factory} service is exposed.
  *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  * @see IPojoFactory
@@ -182,16 +180,10 @@
         } catch (ConfigurationException e) {
             // An exception occurs while executing the configure or start
             // methods.
-            if (instance != null) {
-                instance.dispose();
-                instance = null;
-            }
+            instance.dispose();
             throw e;
         } catch (Throwable e) { // All others exception are handled here.
-            if (instance != null) {
-                instance.dispose();
-                instance = null;
-            }
+            instance.dispose();
             m_logger.log(Logger.ERROR, e.getMessage(), e);
             throw new ConfigurationException(e.getMessage());
         }
@@ -202,7 +194,7 @@
      * Defines a class.
      * This method needs to be synchronized to avoid that the classloader
      * is created twice.
-     * This method delegate the <code>define</code> method invocation to the
+     * This method delegates the <code>define</code> method invocation to the
      * factory classloader.
      *
      * @param name   the qualified name of the class
@@ -210,32 +202,18 @@
      * @param domain the protection domain of the class
      * @return the defined class object
      */
-    public synchronized Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+    public synchronized Class<? extends Object> defineClass(String name, byte[] clazz, ProtectionDomain domain) {
         if (!m_useFactoryClassloader) {
             m_logger.log(Log.WARNING, "A class definition was required even without the factory classloader enabled");
         }
 
         if (m_classLoader == null) {
-            m_classLoader = new FactoryClassloader();
+            m_classLoader = new FactoryClassloader(this);
         }
         return m_classLoader.defineClass(name, clazz, domain);
     }
 
     /**
-     * Returns the URL of a resource.
-     * This methods delegates the invocation to the
-     * {@link Bundle#getResource(String)} method.
-     *
-     * @param resName the resource name
-     * @return the URL of the resource
-     */
-    public URL getResource(String resName) {
-        //No synchronization needed, the context is immutable and
-        //the call is managed by the underlying framework.
-        return m_context.getBundle().getResource(resName);
-    }
-
-    /**
      * Loads a class. This method checks if the class
      * to load is the implementation class or not.
      * If it is, the factory classloader is used, else
@@ -260,9 +238,7 @@
      * This method is not called when holding the monitor lock.
      */
     public void starting() {
-        if (m_tracker != null) {
-            return; // Already started
-        } else {
+        if (m_tracker == null) {
             if (m_requiredHandlers.size() != 0) {
                 try {
                     String filter = "(&(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" + "(factory.state=1)" + ")";
@@ -274,6 +250,7 @@
                 }
             }
         }
+        // Else, the tracking has already started.
     }
 
     /**
@@ -314,10 +291,9 @@
      * @return the required handler list.
      */
     public List getRequiredHandlerList() {
-        List list = new ArrayList();
+        List<RequiredHandler> list = new ArrayList<RequiredHandler>();
         Element[] elems = m_componentMetadata.getElements();
-        for (int i = 0; i < elems.length; i++) {
-            Element current = elems[i];
+        for (Element current : elems) {
             if (!"manipulation".equals(current.getName())) { // Remove the manipulation element
                 RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());
                 if (!list.contains(req)) {
@@ -359,8 +335,8 @@
         String v = System.getProperty(HANDLER_AUTO_PRIMITIVE);
         if (v != null && v.length() != 0) {
             String[] hs = ParseUtils.split(v, ",");
-            for (int i = 0; i < hs.length; i++) {
-                String h = hs[i].trim();
+            for (String h1 : hs) {
+                String h = h1.trim();
                 String[] segments = ParseUtils.split(h, ":");
                 RequiredHandler rq = null;
                 if (segments.length == 2) { // External handler
@@ -378,7 +354,6 @@
             }
         }
 
-
         return list;
     }
 
@@ -434,8 +409,8 @@
      */
     public synchronized 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);
+        for (Object m_requiredHandler : m_requiredHandlers) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandler;
             if (reference.equals(req.getReference())) {
                 req.unRef(); // This method will unget the service.
                 computeFactoryState();
@@ -480,251 +455,4 @@
         return m_classLoader;
     }
 
-    /**
-     * this class defines the classloader attached to a factory.
-     * This class loader is used to load the implementation (e.g. manipulated)
-     * class.
-     *
-     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
-     * @see ClassLoader
-     */
-    private class FactoryClassloader extends ClassLoader {
-
-        /**
-         * The map of defined classes [Name, Class Object].
-         */
-        private final Map m_definedClasses = new HashMap();
-
-        /**
-         * The defineClass method.
-         *
-         * @param name   name 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[] 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;
-        }
-
-        /**
-         * Returns the URL of the required resource.
-         *
-         * @param arg the name of the resource to find.
-         * @return the URL of the resource.
-         * @see java.lang.ClassLoader#getResource(java.lang.String)
-         */
-        public URL getResource(String arg) {
-            return m_context.getBundle().getResource(arg);
-        }
-
-        /**
-         * Loads the given class.
-         *
-         * @param name    the name of the class
-         * @param resolve should be the class resolve now ?
-         * @return the loaded class object
-         * @throws ClassNotFoundException if the class to load is not found
-         * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
-         * @see java.lang.ClassLoader#loadClass(String, boolean)
-         */
-        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            return m_context.getBundle().loadClass(name);
-        }
-    }
-
-    /**
-     * This class defines the description of primitive (non-composite) component
-     * types. An instance of this class will be returned when invoking the
-     * {@link ComponentFactory#getComponentDescription()} method.
-     *
-     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
-     */
-    private final class PrimitiveTypeDescription extends ComponentTypeDescription {
-
-        /*
-           * Set to keep component's all super-class class-names.
-           */
-        private Set m_superClasses = new HashSet();
-        /*
-           * Set to keep component's all interface class-names.
-           */
-        private Set m_interfaces = new HashSet();
-
-        /**
-         * Creates a PrimitiveTypeDescription object.
-         *
-         * @param factory the factory attached to this component type description.
-         */
-        public PrimitiveTypeDescription(IPojoFactory factory) {
-            super(factory);
-
-            try {
-                // The inspection can be done only for primitive components
-                if (m_classname != null) {
-                    // Read inherited classes and interfaces into given Sets.
-                    new InheritanceInspector(getPojoMetadata(), getBundleContext().getBundle()).
-                            computeInterfacesAndSuperClasses(m_interfaces, m_superClasses);
-                }
-            } catch (ClassNotFoundException e) {
-                m_interfaces.clear();
-                m_superClasses.clear();
-            }
-
-        }
-
-        /**
-         * Computes the properties to publish.
-         * The <code>component.class</code> property contains the implementation 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;
-        }
-
-        /**
-         * Adds 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));
-
-            /* Adding interfaces and super-classes of component into description */
-            Element inheritance = new Element("Inherited", "");
-
-            inheritance.addAttribute(new Attribute("Interfaces", m_interfaces.toString()));
-            inheritance.addAttribute(new Attribute("SuperClasses", m_superClasses.toString()));
-
-            elem.addElement(inheritance);
-
-            return elem;
-        }
-
-        /**
-         * This class is used to collect interfaces and super-classes of given component in specified Sets.
-         *
-         * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
-         */
-        private final class InheritanceInspector {
-            /*
-                * PojoMetadata of target Component.
-                */
-            private PojoMetadata m_pojoMetadata;
-            /*
-                * Bundle exposing target component.
-                */
-            private Bundle m_bundle;
-
-
-            /**
-             * Creates a TypeCollector object
-             *
-             * @param pojoMetadata PojoMetadata describing Component.
-             * @param bundle       Bundle which has been exposed the intended Component.
-             */
-            public InheritanceInspector(PojoMetadata pojoMetadata, Bundle bundle) {
-                m_pojoMetadata = pojoMetadata;
-                m_bundle = bundle;
-            }
-
-            /**
-             * Collect interfaces implemented by the POJO into given Sets.
-             *
-             * @param interfaces : the set of implemented interfaces
-             * @param classes    : the set of extended classes
-             * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
-             */
-            public void computeInterfacesAndSuperClasses(Set interfaces, Set classes) throws ClassNotFoundException {
-                String[] immediateInterfaces = m_pojoMetadata.getInterfaces();
-                String parentClass = m_pojoMetadata.getSuperClass();
-
-                // First iterate on found specification in manipulation metadata
-                for (int i = 0; i < immediateInterfaces.length; i++) {
-                    interfaces.add(immediateInterfaces[i]);
-                    // Iterate on interfaces implemented by the current interface
-                    Class clazz = m_bundle.loadClass(immediateInterfaces[i]);
-                    collectInterfaces(clazz, interfaces, m_bundle);
-                }
-
-                // Look for parent class.
-                if (parentClass != null) {
-                    Class clazz = m_bundle.loadClass(parentClass);
-                    collectInterfacesFromClass(clazz, interfaces, m_bundle);
-                    classes.add(parentClass);
-                    collectParentClassesFromClass(clazz, classes, m_bundle);
-                }
-
-                // Removing Object Class from the inherited classes list.
-                classes.remove(Object.class.getName());
-            }
-
-            /**
-             * Look for inherited interfaces.
-             *
-             * @param clazz  : interface name to explore (class object)
-             * @param acc    : set (accumulator)
-             * @param bundle : bundle
-             * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
-             */
-            private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
-                Class[] clazzes = clazz.getInterfaces();
-                for (int i = 0; i < clazzes.length; i++) {
-                    acc.add(clazzes[i].getName());
-                    collectInterfaces(clazzes[i], acc, bundle);
-                }
-            }
-
-            /**
-             * Collect interfaces for the given class.
-             * This method explores super class to.
-             *
-             * @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 clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
-                Class[] clazzes = clazz.getInterfaces();
-                for (int i = 0; i < clazzes.length; i++) {
-                    acc.add(clazzes[i].getName());
-                    collectInterfaces(clazzes[i], acc, bundle);
-                }
-                // Iterate on parent classes
-                Class sup = clazz.getSuperclass();
-                if (sup != null) {
-                    collectInterfacesFromClass(sup, acc, bundle);
-                }
-            }
-
-            /**
-             * Collect parent classes for the given class.
-             *
-             * @param clazz  : class object.
-             * @param acc    : set of extended classes (accumulator)
-             * @param bundle : bundle.
-             * @throws ClassNotFoundException : occurs if an interface cannot be load.
-             */
-            private void collectParentClassesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
-                Class parent = clazz.getSuperclass();
-                if (parent != null) {
-                    acc.add(parent.getName());
-                    collectParentClassesFromClass(parent, acc, bundle);
-                }
-            }
-        }
-    }
 }
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
new file mode 100644
index 0000000..df3b34b
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationTracker.java
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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.extender.internal.Extender;
+import org.apache.felix.ipojo.util.Log;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.ServiceLocator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.*;
+import org.osgi.service.cm.ConfigurationException;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * An object tracking configuration from the configuration admin. It delegates to the underlying factories or
+ * component instance the action.
+ * <p/>
+ * This class implements a Configuration Listener, so events are received asynchronously.
+ */
+public class ConfigurationTracker implements ConfigurationListener {
+
+    /**
+     * The tracker instance.
+     */
+    private static ConfigurationTracker m_singleton;
+    private final ServiceRegistration<ConfigurationListener> m_registration;
+    private final BundleContext m_context;
+    private final Logger m_logger;
+    private Map<String, IPojoFactory> m_factories = new HashMap<String, IPojoFactory>();
+
+    public ConfigurationTracker() {
+        m_context = Extender.getIPOJOBundleContext();
+        m_logger = new Logger(m_context, "iPOJO Configuration Admin listener", Log.INFO);
+        // register as listener for configurations
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(Constants.SERVICE_DESCRIPTION, "iPOJO Configuration Admin Listener");
+        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        m_registration = m_context.registerService(ConfigurationListener.class, this, props);
+    }
+
+    public static void initialize() {
+        synchronized (ConfigurationTracker.class) {
+            if (m_singleton == null) {
+                m_singleton = new ConfigurationTracker();
+            }
+        }
+    }
+
+    public static void shutdown() {
+        m_singleton.dispose();
+    }
+
+    public static ConfigurationTracker get() {
+        return m_singleton;
+    }
+
+    /**
+     * This method must be called by the iPOJO System itself, and only once.
+     */
+    public synchronized void dispose() {
+        if (m_registration != null) {
+            m_registration.unregister();
+        }
+        m_factories.clear();
+    }
+
+    public synchronized void registerFactory(IPojoFactory factory) {
+        m_factories.put(factory.getFactoryName(), factory);
+
+        ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+                .class, m_context);
+        final ConfigurationAdmin admin = locator.get();
+        if (admin == null) {
+            return;
+        }
+
+        List<Configuration> configurations = findFactoryConfiguration(admin, factory);
+        for (Configuration configuration : configurations) {
+            try {
+                factory.updated(configuration.getPid(), configuration.getProperties());
+            } catch (ConfigurationException e) {
+                m_logger.log(Log.ERROR, "Cannot reconfigure instance " + configuration.getPid() + " from " +
+                        configuration.getFactoryPid() + " with the configuration : " + configuration.getProperties(),
+                        e);
+            }
+        }
+    }
+
+    public synchronized void instanceCreated(IPojoFactory factory, ComponentInstance instance) {
+        ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+                .class, m_context);
+        final ConfigurationAdmin admin = locator.get();
+        if (admin == null) {
+            return;
+        }
+
+        Configuration configuration = findSingletonConfiguration(admin, instance.getInstanceName());
+        if (configuration != null) {
+            Hashtable<String, Object> conf = copyConfiguration(configuration);
+            if (!conf.containsKey(Factory.INSTANCE_NAME_PROPERTY)) {
+                conf.put(Factory.INSTANCE_NAME_PROPERTY, configuration.getPid());
+            }
+            try {
+                instance.getFactory().reconfigure(conf);
+            } catch (UnacceptableConfiguration unacceptableConfiguration) {
+                m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + configuration.getPid() + " - the " +
+                        "configuration is unacceptable", unacceptableConfiguration);
+            } catch (MissingHandlerException e) {
+                m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + configuration.getPid() + " - factory is " +
+                        "invalid", e);
+            }
+        }
+    }
+
+    public synchronized void unregisterFactory(IPojoFactory factory) {
+        m_factories.remove(factory.getFactoryName());
+    }
+
+    public void configurationEvent(ConfigurationEvent event) {
+        String pid = event.getPid();
+        String factoryPid = event.getFactoryPid();
+
+        if (factoryPid == null) {
+            ComponentInstance instance = retrieveInstance(pid);
+            if (instance != null) {
+                manageConfigurationEventForSingleton(instance, event);
+            }
+        } else {
+            IPojoFactory factory = retrieveFactory(factoryPid);
+            if (factory != null) {
+                manageConfigurationEventForFactory(factory, event);
+            }
+            // Else the factory is unknown, do nothing.
+        }
+
+    }
+
+    private void manageConfigurationEventForFactory(final IPojoFactory factory, final ConfigurationEvent event) {
+        ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+                .class, m_context);
+
+        switch (event.getType()) {
+            case ConfigurationEvent.CM_DELETED:
+                factory.deleted(event.getPid());
+                break;
+            case ConfigurationEvent.CM_UPDATED:
+                final ConfigurationAdmin admin = locator.get();
+                if (admin == null) {
+                    break;
+                }
+                final Configuration config = getConfiguration(admin, event.getPid(),
+                        factory.getBundleContext().getBundle().getLocation());
+                if (config != null) {
+                    try {
+                        factory.updated(event.getPid(), config.getProperties());
+                    } catch (org.osgi.service.cm.ConfigurationException e) {
+                        m_logger.log(Log.ERROR, "Cannot reconfigure instance " + event.getPid() + " with the new " +
+                                "configuration " + config.getProperties(), e);
+                    }
+                }
+            default:
+                // To nothing.
+        }
+
+        locator.unget();
+    }
+
+    private void manageConfigurationEventForSingleton(final ComponentInstance instance,
+                                                      final ConfigurationEvent event) {
+        ServiceLocator<ConfigurationAdmin> locator = new ServiceLocator<ConfigurationAdmin>(ConfigurationAdmin
+                .class, m_context);
+
+        switch (event.getType()) {
+            case ConfigurationEvent.CM_DELETED:
+                instance.dispose();
+                break;
+            case ConfigurationEvent.CM_UPDATED:
+                final ConfigurationAdmin admin = locator.get();
+                if (admin == null) {
+                    break;
+                }
+                final Configuration config = getConfiguration(admin, event.getPid(),
+                        instance.getFactory().getBundleContext().getBundle().getLocation());
+                if (config != null) {
+                    Hashtable<String, Object> conf = copyConfiguration(config);
+                    if (!conf.containsKey(Factory.INSTANCE_NAME_PROPERTY)) {
+                        conf.put(Factory.INSTANCE_NAME_PROPERTY, event.getPid());
+                    }
+                    try {
+                        instance.getFactory().reconfigure(conf);
+                    } catch (UnacceptableConfiguration unacceptableConfiguration) {
+                        m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + event.getPid() + " - the " +
+                                "configuration is unacceptable", unacceptableConfiguration);
+                    } catch (MissingHandlerException e) {
+                        m_logger.log(Log.ERROR, "Cannot reconfigure the instance " + event.getPid() + " - factory is " +
+                                "invalid", e);
+                    }
+                }
+            default:
+                // To nothing.
+        }
+
+        locator.unget();
+    }
+
+    private Hashtable<String, Object> copyConfiguration(Configuration config) {
+        Hashtable<String, Object> conf = new Hashtable<String, Object>();
+        // Copy configuration
+        Enumeration keys = config.getProperties().keys();
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            conf.put(key, config.getProperties().get(key));
+        }
+        return conf;
+    }
+
+    private IPojoFactory retrieveFactory(String factoryPid) {
+        synchronized (this) {
+            return m_factories.get(factoryPid);
+        }
+    }
+
+    private ComponentInstance retrieveInstance(String instanceName) {
+        Collection<IPojoFactory> factories;
+        synchronized (this) {
+            factories = m_factories.values();
+        }
+        for (IPojoFactory factory : factories) {
+            ComponentInstance instance = factory.getInstanceByName(instanceName);
+            if (instance != null) {
+                return instance;
+            }
+        }
+        return null;
+    }
+
+    private Configuration getConfiguration(final ConfigurationAdmin admin, final String pid,
+                                           final String bundleLocation) {
+        if (admin == null) {
+            return null;
+        }
+
+        try {
+            // Even if it is possible, we don't build the filter with bundle.location to detect the case where the
+            // configuration exists but can't be managed by iPOJO.
+            final Configuration cfg = admin.getConfiguration(pid);
+
+            if (bundleLocation.equals(cfg.getBundleLocation())) {
+                return cfg;
+            }
+
+            // Multi-location with only ?
+            if (cfg.getBundleLocation().equals("?")) {
+                return cfg;
+            }
+
+            // Multi-location specifying the pid
+            if (cfg.getBundleLocation().startsWith("?")) {
+                String sn = cfg.getBundleLocation().substring(1); // Remove ?
+                if (sn.equals(pid)) {
+                    return cfg;
+                }
+            }
+
+            // configuration belongs to another bundle, cannot be used here
+            m_logger.log(Log.ERROR, "Cannot use configuration pid=" + pid + " for bundle "
+                    + bundleLocation + " because it belongs to bundle " + cfg.getBundleLocation());
+        } catch (IOException ioe) {
+            m_logger.log(Log.WARNING, "Failed reading configuration for pid=" + pid, ioe);
+        }
+
+        return null;
+    }
+
+    public List<Configuration> findFactoryConfiguration(final ConfigurationAdmin admin, final IPojoFactory factory) {
+        final String filter = "(service.factoryPid=" + factory.getFactoryName() + ")";
+        return findConfigurations(admin, filter);
+    }
+
+    public Configuration findSingletonConfiguration(final ConfigurationAdmin admin, final String pid) {
+        final String filter = "(service.pid=" + pid + ")";
+        List<Configuration> list = findConfigurations(admin, filter);
+        if (list.isEmpty()) {
+            return null;
+        } else {
+            return list.get(0);
+        }
+    }
+
+    private List<Configuration> findConfigurations(final ConfigurationAdmin admin, final String filter) {
+        List<Configuration> configurations = Collections.emptyList();
+        if (admin == null) {
+            return configurations;
+        }
+
+        try {
+            Configuration[] list = admin.listConfigurations(filter);
+            if (list == null) {
+                return configurations;
+            } else {
+                return Arrays.asList(list);
+            }
+        } catch (InvalidSyntaxException e) {
+            m_logger.log(Log.ERROR, "Invalid Configuration selection filter " + filter, e);
+        } catch (IOException e) {
+            m_logger.log(Log.ERROR, "Error when retrieving configurations for filter=" + filter, e);
+        }
+        return configurations;
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java
new file mode 100644
index 0000000..eb1d5d7
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryClassloader.java
@@ -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.
+ */
+
+package org.apache.felix.ipojo;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class defines the classloader attached to a factory.
+ * This class loader is used to load the implementation (e.g. manipulated)
+ * class.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @see ClassLoader
+ */
+class FactoryClassloader extends ClassLoader {
+
+    /**
+     * The map of defined classes [Name, Class Object].
+     */
+    private final Map<String, Class<?>> m_definedClasses = new HashMap<String, Class<?>>();
+    private ComponentFactory factory;
+
+    public FactoryClassloader(ComponentFactory factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * The defineClass method.
+     *
+     * @param name   name 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[] clazz, ProtectionDomain domain) {
+        if (m_definedClasses.containsKey(name)) {
+            return m_definedClasses.get(name);
+        }
+        Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
+        m_definedClasses.put(name, clas);
+        return clas;
+    }
+
+    /**
+     * Returns the URL of the required resource.
+     *
+     * @param arg the name of the resource to find.
+     * @return the URL of the resource.
+     * @see ClassLoader#getResource(String)
+     */
+    public URL getResource(String arg) {
+        return factory.m_context.getBundle().getResource(arg);
+    }
+
+    /**
+     * Loads the given class.
+     *
+     * @param name    the name of the class
+     * @param resolve should be the class resolve now ?
+     * @return the loaded class object
+     * @throws ClassNotFoundException if the class to load is not found
+     * @see ClassLoader#loadClass(String, boolean)
+     * @see ClassLoader#loadClass(String, boolean)
+     */
+    protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        return factory.m_context.getBundle().loadClass(name);
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
index 85cb3f1..a5b34a2 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -35,8 +35,10 @@
 /**

  * This class defines common mechanisms of iPOJO component factories

  * (i.e. component type).

- * This class implements both the Factory and ManagedServiceFactory

- * services.

+ *

+ * The factory is also tracking Factory configuration from the configuration admin to created / delete and update

+ * instances from this factory.

+ *

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

  */

 public abstract class IPojoFactory implements Factory, ManagedServiceFactory {

@@ -49,7 +51,7 @@
      * The list of the managed instance name.

      * This list is shared by all factories and is used to assert name uniqueness.

      */

-    protected static final List INSTANCE_NAME = Collections.synchronizedList(new ArrayList());

+    protected static final List<String> INSTANCE_NAME = Collections.synchronizedList(new ArrayList<String>());

 

     /**

      * The component type description exposed by the {@link Factory} service.

@@ -60,7 +62,7 @@
      * The list of the managed instance managers.

      * The key of this map is the name (i.e. instance names) of the created instance

      */

-    protected final Map m_componentInstances = new HashMap();

+    protected final Map<String, ComponentInstance> m_componentInstances = new HashMap<String, ComponentInstance>();

 

     /**

      * The component type metadata.

@@ -82,13 +84,13 @@
     /**

      * The list of required handlers.

      */

-    protected List m_requiredHandlers = new ArrayList();

+    protected List<RequiredHandler> m_requiredHandlers = new ArrayList<RequiredHandler>();

 

     /**

      * The list of factory state listeners.

      * @see FactoryStateListener

      */

-    protected List m_listeners = new ArrayList(1);

+    protected List<FactoryStateListener> m_listeners = new ArrayList<FactoryStateListener>(1);

 

     /**

      * The logger for the factory.

@@ -202,7 +204,7 @@
      * Each sub-type must override this method.

      * @return the required handler list

      */

-    public abstract List getRequiredHandlerList();

+    public abstract List<RequiredHandler> getRequiredHandlerList();

 

     /**

      * Creates an instance.

@@ -292,14 +294,15 @@
         // Here we are sure to be valid until the end of the method.

         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);

+            handlers[i] = getHandler(m_requiredHandlers.get(i), serviceContext);

         }

 

         try {

             ComponentInstance instance = createInstance(configuration, context, handlers);

             m_componentInstances.put(name, instance);

             m_logger.log(Logger.INFO, "Instance " + name + " from factory " + m_factoryName + " created");

+            // Register the instance on the ConfigurationTracker to be updated if needed.

+            ConfigurationTracker.get().instanceCreated(this, instance);

             return instance;

         } catch (ConfigurationException e) {

             INSTANCE_NAME.remove(name);

@@ -361,10 +364,9 @@
      * @return the 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);

+    public List<String> getMissingHandlers() {

+        List<String> list = new ArrayList<String>();

+        for (RequiredHandler req : m_requiredHandlers) {

             if (req.getReference() == null) {

                 list.add(req.getFullName());

             }

@@ -389,10 +391,9 @@
      * @return the list of required handlers.

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

      */

-    public synchronized List getRequiredHandlers() {

-        List list = new ArrayList();

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

-            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+    public synchronized List<String> getRequiredHandlers() {

+        List<String> list = new ArrayList<String>();

+        for (RequiredHandler req : m_requiredHandlers) {

             list.add(req.getFullName());

         }

         return list;

@@ -409,6 +410,17 @@
     }

 

     /**

+     * Gets a component instance created by the current factory.

+     * @param name the instance name

+     * @return the component instance, {@literal null} if not found

+     */

+    public ComponentInstance getInstanceByName(String name) {

+        synchronized (this) {

+            return m_componentInstances.get(name);

+        }

+    }

+

+    /**

      * Checks if the configuration is acceptable.

      * @param conf the configuration to test.

      * @return <code>true</code> if the configuration is acceptable.

@@ -435,7 +447,8 @@
      * @throws UnacceptableConfiguration if the configuration is unacceptable.

      * @throws MissingHandlerException if an handler is missing.

      */

-    public void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {

+    public void checkAcceptability(Dictionary<String, ?> conf) throws UnacceptableConfiguration,

+            MissingHandlerException {

         PropertyDescription[] props;

         synchronized (this) {

             if (m_state == Factory.INVALID) {

@@ -447,14 +460,15 @@
 

         // Check that the configuration does not override immutable properties.

 

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

+        for (PropertyDescription prop : props) {

             // 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 tries to override an immutable property.

+            if (prop.isImmutable() && conf.get(prop.getName()) != null) {

+                throw new UnacceptableConfiguration("The property " + prop + " cannot be overridden : immutable " +

+                        "property"); // The instance configuration tries to override an immutable property.

             }

             // Is the property required ?

-            if (props[i].isMandatory() && props[i].getValue() == null && conf.get(props[i].getName()) == null) {

-                throw new UnacceptableConfiguration("The mandatory property " + props[i].getName() + " is missing"); // The property must be set.

+            if (prop.isMandatory() && prop.getValue() == null && conf.get(prop.getName()) == null) {

+                throw new UnacceptableConfiguration("The mandatory property " + prop.getName() + " is missing"); // The property must be set.

             }

         }

     }

@@ -480,7 +494,7 @@
             name = (String) properties.get("name");

         }

 

-        ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);

+        ComponentInstance instance = m_componentInstances.get(name);

         if (instance == null) { // The instance does not exists.

             return;

         }

@@ -520,13 +534,16 @@
             m_sr.unregister();

             m_sr = null;

         }

+

+        ConfigurationTracker.get().unregisterFactory(this);

+

         stopping(); // Method called when holding the lock.

         int oldState = m_state; // Create a variable to store the old state. Using a variable is important as

                                 // after the next instruction, the getState() method must return INVALID.

         m_state = INVALID; // Set here to avoid to create instances during the stops.

 

-        Set col = m_componentInstances.keySet();

-        Iterator it = col.iterator();

+        Set<String> col = m_componentInstances.keySet();

+        Iterator<String> it = col.iterator();

         instances = new ComponentInstance[col.size()]; // Stack confinement

         int index = 0;

         while (it.hasNext()) {

@@ -535,23 +552,23 @@
         }

 

         if (oldState == VALID) { // Check if the old state was valid.

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

-                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);

+            for (FactoryStateListener listener : m_listeners) {

+                listener.stateChanged(this, INVALID);

             }

         }

 

         // Dispose created instances.

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

-            ComponentInstance instance = instances[i];

+        for (ComponentInstance instance : instances) {

             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();

+        for (RequiredHandler req : m_requiredHandlers) {

+            req.unRef();

         }

+

         m_described = false;

         m_componentDesc = null;

         m_componentInstances.clear();

@@ -601,13 +618,17 @@
         if (m_isPublic) {

             // Exposition of the factory service

             if (m_componentDesc == null) {

-                System.out.println("Description of " + m_factoryName + " " + m_componentDesc);

+                m_logger.log(Logger.ERROR, "Unexpected state, the description of " + m_factoryName + "  is null");

+                return;

             }

             BundleContext bc = SecurityHelper.selectContextToRegisterServices(m_componentDesc.getFactoryInterfacesToPublish(),

                     m_context, getIPOJOBundleContext());

             m_sr =

                     bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc

                             .getPropertiesToPublish());

+

+            // Register the factory on the ConfigurationTracker

+            ConfigurationTracker.get().registerFactory(this);

         }

 

         m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");

@@ -637,11 +658,12 @@
      * @param properties the new 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)

+     * TODO this method should disappear.

      */

     public void updated(String name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {

         ComponentInstance instance;

         synchronized (this) {

-            instance = (ComponentInstance) m_componentInstances.get(name);

+            instance = m_componentInstances.get(name);

         }

 

         if (instance == null) {

@@ -677,6 +699,7 @@
      * Deletes an instance.

      * @param name the name of the instance to delete

      * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)

+     * todo this method should disappear.

      */

     public synchronized void deleted(String name) {

         INSTANCE_NAME.remove(name);

@@ -707,9 +730,7 @@
      * This method is called with the lock.

      */

     protected void computeDescription() {

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

-            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

-

+        for (RequiredHandler req : m_requiredHandlers) {

             if (getHandler(req, null) == null) {

                 // TODO this does not really looks good.

                 m_logger.log(Logger.ERROR, "Cannot extract handler object from " + m_factoryName + " " + req

@@ -720,7 +741,7 @@
                     handler.setFactory(this);

                     handler.initializeComponentFactory(m_componentDesc, m_componentMetadata);

                     ((Pojo) handler).getComponentInstance().dispose();

-                } catch (org.apache.felix.ipojo.ConfigurationException e) {

+                } catch (ConfigurationException e) {

                     ((Pojo) handler).getComponentInstance().dispose();

                     m_logger.log(Logger.ERROR, e.getMessage());

                     stop();

@@ -739,8 +760,7 @@
      */

     protected void computeFactoryState() {

         boolean isValid = true;

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

-            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);

+        for (RequiredHandler req : m_requiredHandlers) {

             if (req.getReference() == null) {

                 isValid = false;

                 break;

@@ -760,25 +780,24 @@
                 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);

+                for (FactoryStateListener listener : m_listeners) {

+                    listener.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);

+                for (FactoryStateListener listener : m_listeners) {

+                    listener.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]);

+                // We must create a copy to avoid concurrent exceptions

+                Set<? extends String> keys = new HashSet<String>(m_componentInstances.keySet());

+                for (String key : keys) {

+                    ComponentInstance instance = m_componentInstances.get(key);

                     if (instance.getState() != ComponentInstance.DISPOSED) {

                         instance.dispose();

                     }

@@ -790,8 +809,6 @@
                 if (m_sr != null) {

                     m_sr.setProperties(m_componentDesc.getPropertiesToPublish());

                 }

-

-                return;

             }

         }

     }

@@ -803,7 +820,7 @@
      * @param ref the service reference.

      * @return <code>true</code> if the service reference can fulfill the handler requirement

      */

-    protected boolean match(RequiredHandler req, ServiceReference ref) {

+    protected boolean match(RequiredHandler req, ServiceReference<? extends Object> 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)) {

@@ -927,7 +944,7 @@
                 return null;

             }

             if (m_factory == null) {

-                m_factory = (HandlerFactory) m_context.getService(getReference());

+                m_factory = m_context.getService(getReference());

             }

             return m_factory;

         }

@@ -952,7 +969,7 @@
             return m_namespace;

         }

 

-        public ServiceReference getReference() {

+        public ServiceReference<? extends HandlerFactory> getReference() {

             return m_reference;

         }

 

diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.java
new file mode 100644
index 0000000..6e61112
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveTypeDescription.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;
+
+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.osgi.framework.Bundle;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class defines the description of primitive (non-composite) component
+ * types. An instance of this class will be returned when invoking the
+ * {@link org.apache.felix.ipojo.ComponentFactory#getComponentDescription()} method.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+final class PrimitiveTypeDescription extends ComponentTypeDescription {
+
+    /**
+     * Set to keep component's all super-class class-names.
+     */
+    private Set<String> m_superClasses = new HashSet<String>();
+
+    /**
+     * Set to keep component's all interface class-names.
+     */
+    private Set<String> m_interfaces = new HashSet<String>();
+
+    /**
+     * The described component factory.
+     */
+    private ComponentFactory m_factory;
+
+    /**
+     * Creates a PrimitiveTypeDescription object.
+     *
+     * @param factory the m_factory attached to this component type description.
+     */
+    public PrimitiveTypeDescription(ComponentFactory factory) {
+        super(factory);
+        this.m_factory = factory;
+
+        try {
+            // The inspection can be done only for primitive components
+            if (factory.getClassName() != null) {
+                // Read inherited classes and interfaces into given Sets.
+                new InheritanceInspector(factory.getPojoMetadata(), getBundleContext().getBundle()).
+                        computeInterfacesAndSuperClasses(m_interfaces, m_superClasses);
+            }
+        } catch (ClassNotFoundException e) {
+            m_interfaces.clear();
+            m_superClasses.clear();
+        }
+
+    }
+
+    /**
+     * Computes the properties to publish.
+     * The <code>component.class</code> property contains the implementation class name.
+     *
+     * @return the dictionary of properties to publish
+     * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+     */
+    public Dictionary<String, Object> getPropertiesToPublish() {
+        Dictionary<String, Object> dict = super.getPropertiesToPublish();
+        if (m_factory.getClassName() != null) {
+            dict.put("component.class", m_factory.getClassName());
+        }
+        return dict;
+    }
+
+    /**
+     * Adds 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_factory.getClassName()));
+
+        /* Adding interfaces and super-classes of component into description */
+        Element inheritance = new Element("Inherited", "");
+
+        inheritance.addAttribute(new Attribute("Interfaces", m_interfaces.toString()));
+        inheritance.addAttribute(new Attribute("SuperClasses", m_superClasses.toString()));
+
+        elem.addElement(inheritance);
+
+        return elem;
+    }
+
+    /**
+     * This class is used to collect interfaces and super-classes of given component in specified Sets.
+     *
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    private final class InheritanceInspector {
+        /*
+            * PojoMetadata of target Component.
+            */
+        private PojoMetadata m_pojoMetadata;
+        /*
+            * Bundle exposing target component.
+            */
+        private Bundle m_bundle;
+
+
+        /**
+         * Creates a TypeCollector object
+         *
+         * @param pojoMetadata PojoMetadata describing Component.
+         * @param bundle       Bundle which has been exposed the intended Component.
+         */
+        public InheritanceInspector(PojoMetadata pojoMetadata, Bundle bundle) {
+            m_pojoMetadata = pojoMetadata;
+            m_bundle = bundle;
+        }
+
+        /**
+         * Collect interfaces implemented by the POJO into given Sets.
+         *
+         * @param interfaces : the set of implemented interfaces
+         * @param classes    : the set of extended classes
+         * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+         */
+        public void computeInterfacesAndSuperClasses(Set<String> interfaces, Set<String> classes) throws ClassNotFoundException {
+            String[] immediateInterfaces = m_pojoMetadata.getInterfaces();
+            String parentClass = m_pojoMetadata.getSuperClass();
+
+            // First iterate on found specification in manipulation metadata
+            for (String immediateInterface : immediateInterfaces) {
+                interfaces.add(immediateInterface);
+                // Iterate on interfaces implemented by the current interface
+                Class<?> clazz = m_bundle.loadClass(immediateInterface);
+                collectInterfaces(clazz, interfaces, m_bundle);
+            }
+
+            // Look for parent class.
+            if (parentClass != null) {
+                Class clazz = m_bundle.loadClass(parentClass);
+                collectInterfacesFromClass(clazz, interfaces, m_bundle);
+                classes.add(parentClass);
+                collectParentClassesFromClass(clazz, classes, m_bundle);
+            }
+
+            // Removing Object Class from the inherited classes list.
+            classes.remove(Object.class.getName());
+        }
+
+        /**
+         * Look for inherited interfaces.
+         *
+         * @param clazz  : interface name to explore (class object)
+         * @param acc    : set (accumulator)
+         * @param bundle : bundle
+         * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+         */
+        private void collectInterfaces(Class<?> clazz, Set<String> acc, Bundle bundle) throws ClassNotFoundException {
+            Class[] clazzes = clazz.getInterfaces();
+            for (Class clazze : clazzes) {
+                acc.add(clazze.getName());
+                collectInterfaces(clazze, acc, bundle);
+            }
+        }
+
+        /**
+         * Collect interfaces for the given class.
+         * This method explores super class to.
+         *
+         * @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<?> clazz, Set<String> acc,
+                                                Bundle bundle) throws ClassNotFoundException {
+            Class[] clazzes = clazz.getInterfaces();
+            for (Class clazze : clazzes) {
+                acc.add(clazze.getName());
+                collectInterfaces(clazze, acc, bundle);
+            }
+            // Iterate on parent classes
+            Class sup = clazz.getSuperclass();
+            if (sup != null) {
+                collectInterfacesFromClass(sup, acc, bundle);
+            }
+        }
+
+        /**
+         * Collect parent classes for the given class.
+         *
+         * @param clazz  : class object.
+         * @param acc    : set of extended classes (accumulator)
+         * @param bundle : bundle.
+         * @throws ClassNotFoundException : occurs if an interface cannot be load.
+         */
+        private void collectParentClassesFromClass(Class<?> clazz, Set<String> acc, Bundle bundle) throws ClassNotFoundException {
+            Class<?> parent = clazz.getSuperclass();
+            if (parent != null) {
+                acc.add(parent.getName());
+                collectParentClassesFromClass(parent, acc, bundle);
+            }
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
index a2d02d6..d1193fb 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
@@ -18,11 +18,6 @@
  */
 package org.apache.felix.ipojo.architecture;
 
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.IPojoFactory;
 import org.apache.felix.ipojo.metadata.Attribute;
@@ -31,34 +26,37 @@
 import org.osgi.framework.Constants;
 import org.osgi.service.cm.ManagedServiceFactory;
 
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
 /**
  * Component Type description.
+ *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class ComponentTypeDescription {
 
     /**
+     * Represented factory.
+     */
+    private final IPojoFactory m_factory;
+    /**
      * Provided service by the component type.
      */
     private String[] m_providedServiceSpecification = new String[0];
-
     /**
      * Configuration Properties accepted by the component type.
      */
     private PropertyDescription[] m_properties = new PropertyDescription[0];
-    
     /*
      * Used by custom handlers to keep and retrieve custom info.
      */
     private Dictionary m_handlerInfoSlot = new Hashtable();
 
     /**
-     * Represented factory.
-     */
-    private final IPojoFactory m_factory;
-
-    /**
      * Constructor.
+     *
      * @param factory : represented factory.
      */
     public ComponentTypeDescription(IPojoFactory factory) {
@@ -67,6 +65,7 @@
 
     /**
      * Gets the attached factory.
+     *
      * @return the factory
      */
     public IPojoFactory getFactory() {
@@ -75,6 +74,7 @@
 
     /**
      * Gets a printable form of the current component type description.
+     *
      * @return printable form of the component type description
      * @see java.lang.Object#toString()
      */
@@ -84,6 +84,7 @@
 
     /**
      * Gets the implementation class of this component type.
+     *
      * @return the component type implementation class name.
      * @deprecated
      */
@@ -93,8 +94,9 @@
 
     /**
      * Gets the component type version.
+     *
      * @return the component type version or
-     * <code>null</code> if not set.
+     *         <code>null</code> if not set.
      */
     public String getVersion() {
         return m_factory.getVersion();
@@ -102,6 +104,7 @@
 
     /**
      * Gets component-type properties.
+     *
      * @return the list of configuration properties accepted by the component type type.
      */
     public PropertyDescription[] getProperties() {
@@ -110,7 +113,8 @@
 
     /**
      * Adds a String property in the component type.
-     * @param name : property name.
+     *
+     * @param name  : property name.
      * @param value : property value.
      */
     public void addProperty(String name, String value) {
@@ -119,8 +123,9 @@
 
     /**
      * Adds a String property in the component type.
-     * @param name : property name.
-     * @param value : property value.
+     *
+     * @param name      : property name.
+     * @param value     : property value.
      * @param immutable : the property is immutable.
      */
     public void addProperty(String name, String value, boolean immutable) {
@@ -130,6 +135,7 @@
 
     /**
      * Adds a configuration properties to the component type.
+     *
      * @param pd : the property to add
      */
     public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
@@ -138,7 +144,9 @@
         // 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(name)) { return; }
+            if (desc.getName().equals(name)) {
+                return;
+            }
         }
 
         PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
@@ -146,35 +154,32 @@
         newProps[m_properties.length] = pd;
         m_properties = newProps;
     }
-    
+
     /**
      * Adds the HandlerInfo for specified handler.
-     * @param handlerNs Handler's namespace
+     *
+     * @param handlerNs   Handler's namespace
      * @param handlerName Handler's name
-     * @param info HandlerInfo associated with the given custom handler.
+     * @param info        HandlerInfo associated with the given custom handler.
      */
-    public void setHandlerInfo(String handlerNs, String handlerName, CustomHandlerInfo info)
-    {
-    	String fullHandlerName = handlerNs + ":" + handlerName;
-    	
-    	if(info == null)
-    	{
-    		m_handlerInfoSlot.remove(fullHandlerName);
-    	}
-    	else
-    	{
-    		m_handlerInfoSlot.put(fullHandlerName, info);
-    	}
+    public void setHandlerInfo(String handlerNs, String handlerName, CustomHandlerInfo info) {
+        String fullHandlerName = handlerNs + ":" + handlerName;
+
+        if (info == null) {
+            m_handlerInfoSlot.remove(fullHandlerName);
+        } else {
+            m_handlerInfoSlot.put(fullHandlerName, info);
+        }
     }
-    
-    public CustomHandlerInfo getHandlerInfo(String handlerNs, String handlerName)
-    {
-    	String fullHandlerName = handlerNs + ":" + handlerName;    	
-    	return (CustomHandlerInfo)m_handlerInfoSlot.get(fullHandlerName);
+
+    public CustomHandlerInfo getHandlerInfo(String handlerNs, String handlerName) {
+        String fullHandlerName = handlerNs + ":" + handlerName;
+        return (CustomHandlerInfo) m_handlerInfoSlot.get(fullHandlerName);
     }
 
     /**
      * Gets the list of provided service offered by instances of this type.
+     *
      * @return the list of the provided service.
      */
     public String[] getprovidedServiceSpecification() {
@@ -183,6 +188,7 @@
 
     /**
      * Adds a provided service to the component type.
+     *
      * @param serviceSpecification : the provided service to add (interface name)
      */
     public void addProvidedServiceSpecification(String serviceSpecification) {
@@ -194,6 +200,7 @@
 
     /**
      * Returns the component-type name.
+     *
      * @return the name of this component type
      */
     public String getName() {
@@ -203,10 +210,11 @@
     /**
      * Computes 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();
+    public Dictionary<String, Object> getPropertiesToPublish() {
+        Hashtable<String, Object> props = new Hashtable<String, Object>();
 
         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.
@@ -222,14 +230,14 @@
         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()));
+        for (PropertyDescription m_property : m_properties) {
+            if (m_property.isImmutable() && m_property.getValue() != null) {
+                props.put(m_property.getName(), m_property.getObjectValue(m_factory.getBundleContext()));
             }
         }
 
         // Add factory state
-        props.put("factory.state", new Integer(m_factory.getState()));
+        props.put("factory.state", m_factory.getState());
 
         return props;
 
@@ -238,14 +246,16 @@
     /**
      * Gets the interfaces published by the factory.
      * By default publish both {@link Factory} and {@link ManagedServiceFactory}.
+     *
      * @return : the list of interface published by the factory.
      */
     public String[] getFactoryInterfacesToPublish() {
-        return new String[] {Factory.class.getName(), ManagedServiceFactory.class.getName()};
+        return new String[]{Factory.class.getName()};
     }
 
     /**
      * Gets the component type description.
+     *
      * @return : the description
      */
     public Element getDescription() {
@@ -253,8 +263,8 @@
 
         desc.addAttribute(new Attribute("name", m_factory.getName()));
         desc.addAttribute(
-                          new Attribute("bundle",
-                                          Long.toString(m_factory.getBundleContext().getBundle().getBundleId())));
+                new Attribute("bundle",
+                        Long.toString(m_factory.getBundleContext().getBundle().getBundleId())));
 
         String state = "valid";
         if (m_factory.getState() == Factory.INVALID) {
@@ -280,24 +290,22 @@
             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].isMandatory()  && m_properties[i].getValue() == null) {
+            if (m_properties[i].isMandatory() && m_properties[i].getValue() == null) {
                 prop.addAttribute(new Attribute("value", "REQUIRED"));
             } else {
                 prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
             }
             desc.addElement(prop);
         }
-        
-        if(m_handlerInfoSlot.size() > 0)
-        {        	
-        	Enumeration keys = m_handlerInfoSlot.keys();
-            
-            while(keys.hasMoreElements())
-            {
-            	String fullHandlerName = (String) keys.nextElement();
-            	
-            	CustomHandlerInfo handlerInfo = (CustomHandlerInfo)m_handlerInfoSlot.get(fullHandlerName);
-            	desc.addElement( handlerInfo.getDescription() );
+
+        if (m_handlerInfoSlot.size() > 0) {
+            Enumeration keys = m_handlerInfoSlot.keys();
+
+            while (keys.hasMoreElements()) {
+                String fullHandlerName = (String) keys.nextElement();
+
+                CustomHandlerInfo handlerInfo = (CustomHandlerInfo) m_handlerInfoSlot.get(fullHandlerName);
+                desc.addElement(handlerInfo.getDescription());
             }
         }
 
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java
index e4994e3..8e9d90c 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/configuration/Instance.java
@@ -19,7 +19,6 @@
 
 package org.apache.felix.ipojo.configuration;
 
-import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.Factory;
 
 import java.util.*;
@@ -49,6 +48,10 @@
         return new Pair<K, T>(k, v);
     }
 
+    public static <K, T> Pair<K, T> entry(K k, T v) {
+        return new Pair<K, T>(k, v);
+    }
+
     public String factory() {
         return factory;
     }
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java
index af074ab..561623c 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/extender/internal/Extender.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.ipojo.extender.internal;
 
+import org.apache.felix.ipojo.ConfigurationTracker;
 import org.apache.felix.ipojo.EventDispatcher;
 import org.apache.felix.ipojo.extender.internal.linker.DeclarationLinker;
 import org.apache.felix.ipojo.extender.internal.processor.*;
@@ -115,6 +116,9 @@
             EventDispatcher.create(context);
         }
 
+        // Initialize ConfigurationTracker
+        ConfigurationTracker.initialize();
+
         BundleProcessor extensionBundleProcessor = new ExtensionBundleProcessor(m_logger);
         BundleProcessor componentsProcessor = new ComponentsBundleProcessor(m_logger);
         BundleProcessor configurationProcessor = new ConfigurationProcessor(m_logger);
@@ -169,6 +173,9 @@
     public void stop(BundleContext context) throws Exception {
         context.removeBundleListener(this);
 
+        //Shutdown ConfigurationTracker
+        ConfigurationTracker.shutdown();
+
         m_processor.stop();
 
         if (DISPATCHER_ENABLED) {
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java
new file mode 100644
index 0000000..bd970d4
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceLocator.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A simple utility class to retrive services from the service registry.
+ */
+public class ServiceLocator<T> {
+
+    private final BundleContext m_context;
+    private final Class<T> m_clazz;
+
+    private ServiceReference<T> m_reference;
+    private T m_service;
+
+    public ServiceLocator(Class<T> clazz, BundleContext context) {
+        m_clazz = clazz;
+        m_context = context;
+    }
+
+    public synchronized T get() {
+         if (m_service != null) {
+                return m_service;
+         }
+
+        m_reference = m_context.getServiceReference(m_clazz);
+        if (m_reference == null) {
+            return null;
+        }
+        m_service = m_context.getService(m_reference);
+
+        return m_service;
+    }
+
+    public synchronized void unget() {
+        m_service = null;
+        if (m_reference != null) {
+            m_context.ungetService(m_reference);
+            m_reference = null;
+        }
+    }
+}