Fix Felix-1114.
Provides a 'updated' attribute in 'Properties' specifying a method called when a reconfiguration is completed:
<properties updated="afterReconfiguration">
    <property ...>
</properties>

The specified method receives a Dictionary containing the <key,value> pairs

Provides the associated annotation:
@Updated
public void afterReconfiguration(Dictionary conf) {
    ...
}

Extend the API to support the 'updated' attribute (setUpdatedMethod(String method))

Add test checking the 'updated' attribute behavior on simple properties, ManagedService reconfiguration and ManagedServiceFactory reconfiguration.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@770759 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/tests/core/configuration/pom.xml b/ipojo/tests/core/configuration/pom.xml
index 46fea3f..7e1b757 100644
--- a/ipojo/tests/core/configuration/pom.xml
+++ b/ipojo/tests/core/configuration/pom.xml
@@ -97,6 +97,25 @@
 					<target>1.4</target>

 				</configuration>

 			</plugin>

+			<!-- Test -->

+			<plugin>

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

+				<artifactId>maven-junit4osgi-plugin 

+				</artifactId>

+				<version>1.1.0-SNAPSHOT</version>

+				<executions>

+					<execution>

+						<goals>

+							<goal>test</goal>

+						</goals>

+						<configuration>

+							<configuration>

+							<org.osgi.http.port>8083</org.osgi.http.port>

+							</configuration>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

 		</plugins>

 	</build>

 </project>

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java
index 32d2fd9..cec3387 100644
--- a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderType1.java
@@ -18,6 +18,7 @@
  */

 package org.apache.felix.ipojo.test.scenarios.component;

 

+import java.util.Dictionary;

 import java.util.Properties;

 

 import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

@@ -33,6 +34,9 @@
     private static FooProviderType1 singleton;

     private static int count = 0;

     

+    private int updated;

+    private Dictionary lastupdated;

+    

     private static FooProviderType1 singleton(BundleContext bc) {

         if (singleton == null) {

             count++;

@@ -66,6 +70,13 @@
         p.put("context", m_context);

         

         p.put("count", new Integer(count));

+        

+        p.put("updated", new Integer(updated));

+        if (lastupdated != null) {

+            p.put("lastupdated", lastupdated);

+        }

+        

+        

 		return p;

 	}

     

@@ -113,5 +124,10 @@
 	    m_foo = foo;

 	    m_context = bc;

 	}

+	

+	public void updated(Dictionary props) {

+        updated++;

+        lastupdated = props;

+    }

 

 }

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java
index d9e5124..9ec08de 100644
--- a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/component/FooProviderTypeDyn.java
@@ -18,6 +18,7 @@
  */

 package org.apache.felix.ipojo.test.scenarios.component;

 

+import java.util.Dictionary;

 import java.util.Properties;

 

 import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

@@ -29,6 +30,8 @@
 	private String[] strAProp;

 	private int[] intAProp;

 	private boolean boolProp;

+    private int updated;

+    private Dictionary lastUpdate;

 

 	public boolean foo() {

 		intProp = 3;

@@ -53,6 +56,12 @@
 		if (intAProp != null) {

 		    p.put("intAProp", intAProp);

 		}

+		

+		p.put("updated", new Integer(updated));

+		if (lastUpdate != null) {

+		    p.put("lastupdated", lastUpdate);

+		}

+		

 		return p;

 	}

 	

@@ -65,5 +74,10 @@
 	public long getLong() { return 1; }

 

 	public Boolean getObject() { return new Boolean(true); }

+	

+	public void updated(Dictionary props) {

+	    updated++;

+	    lastUpdate = props;

+	}

 

 }

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java
index beffe34..144fa4a 100644
--- a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ConfigurationTestSuite.java
@@ -36,6 +36,9 @@
 		ots.addTestSuite(ManagedServiceConfigurableProperties.class);

 		ots.addTestSuite(TestComplexProperties.class);

 		ots.addTestSuite(TestPropertyModifier.class);

+		ots.addTestSuite(UpdatedMethod.class);

+		ots.addTestSuite(UpdatedMethodAndManagedServiceFactory.class);

+		ots.addTestSuite(UpdatedMethodAndManagedService.class);

 		return ots;

 	}

 

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethod.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethod.java
new file mode 100644
index 0000000..9ec6af2
--- /dev/null
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethod.java
@@ -0,0 +1,195 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

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

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

+

+public class UpdatedMethod extends OSGiTestCase {

+	

+	ComponentInstance fooProvider1;

+	ComponentInstance fooProvider2;

+	ComponentInstance fooProvider3;

+	

+	public void setUp() {

+		String type = "CONFIG-FooProviderType-ConfUpdated";

+		

+		Properties p1 = new Properties();

+		p1.put("instance.name","FooProvider-1");

+		fooProvider1 = Utils.getComponentInstance(getContext(), type, p1);

+		

+		Properties p2 = new Properties();

+		p2.put("instance.name","FooProvider-2");

+		p2.put("int", new Integer(4));

+		p2.put("boolean", new Boolean(false));

+		p2.put("string", new String("bar"));

+		p2.put("strAProp", new String[] {"bar", "foo"});

+		p2.put("intAProp", new int[] {1, 2, 3});

+		fooProvider2 = Utils.getComponentInstance(getContext(), type, p2);

+		

+		Properties p3 = new Properties();

+        p3.put("instance.name","FooProvider-3");

+        fooProvider3 = Utils.getComponentInstance(getContext(), "CONFIG-FooProviderType-ConfNoValueUpdated", p3);

+	}

+	

+	public void tearDown() {

+		fooProvider1.dispose();

+		fooProvider2.dispose();

+		fooProvider3.dispose();

+		fooProvider1 = null;

+		fooProvider2 = null;

+		fooProvider3 = null;

+	}

+	

+	public void testComponentTypeConfiguration() {

+		ServiceReference ref = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), fooProvider1.getInstanceName());

+		assertNotNull("Check FooService availability", ref);

+		FooService fs = (FooService) getContext().getService(ref);

+		Properties toCheck = fs.fooProps();

+		

+		Integer intProp = (Integer) toCheck.get("intProp");

+		Boolean boolProp = (Boolean) toCheck.get("boolProp");

+		String strProp = (String) toCheck.get("strProp");

+		String[] strAProp = (String[]) toCheck.get("strAProp");

+		int[] intAProp = (int[]) toCheck.get("intAProp");

+		

+		// Check updated

+		Integer updated = (Integer) toCheck.get("updated");

+		Dictionary dict = (Dictionary) toCheck.get("lastupdated");

+		

+		assertEquals("Check intProp equality (1)", intProp, new Integer(2));

+		assertEquals("Check longProp equality (1)", boolProp, new Boolean(false));

+		assertEquals("Check strProp equality (1)", strProp, new String("foo"));

+		assertNotNull("Check strAProp not nullity (1)", strAProp);

+		String[] v = new String[] {"foo", "bar"};

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

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (1) : " + strAProp[i] + " != " + v[i]); }

+		}

+		assertNotNull("Check intAProp not nullity", intAProp);

+		int[] v2 = new int[] {1, 2, 3};

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

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (1) : " + intAProp[i] + " != " + v2[i]); }

+		}

+		

+		assertEquals("updated count ", 1, updated.intValue());

+		assertEquals("Last updated", 5, dict.size());

+		

+		// change the field value

+		assertTrue("Invoke the fs service", fs.foo());

+		toCheck = fs.fooProps();

+		

+		

+		//	Re-check the property (change)

+		intProp = (Integer) toCheck.get("intProp");

+		boolProp = (Boolean) toCheck.get("boolProp");

+		strProp = (String) toCheck.get("strProp");

+		strAProp = (String[]) toCheck.get("strAProp");

+		intAProp = (int[]) toCheck.get("intAProp");

+		

+		// Check updated

+        updated = (Integer) toCheck.get("updated");

+        dict = (Dictionary) toCheck.get("lastupdated");

+		

+		assertEquals("Check intProp equality (2) ("+intProp+")", intProp, new Integer(3));

+		assertEquals("Check longProp equality (2)", boolProp, new Boolean(true));

+		assertEquals("Check strProp equality (2)", strProp, new String("bar"));

+		assertNotNull("Check strAProp not nullity (2)", strAProp);

+		v = new String[] {"foo", "bar", "baz"};

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

+			if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality (2)"); }

+		}

+		assertNotNull("Check intAProp not nullity (2)", intAProp);

+		v2 = new int[] {3, 2, 1};

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

+			if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality (2) : " + intAProp[i] + " != " + v2[i]); }

+		}

+		

+		// This does not reconfigure...

+        assertEquals("updated count -2 ", 1, updated.intValue());

+        assertEquals("Last update - 2", 5, dict.size());

+        		

+		fs = null;

+		getContext().ungetService(ref);

+	}

+	

+	public void testNoValue() {

+        ServiceReference sr = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), "FooProvider-3");

+        assertNotNull("Check the availability of the FS service", sr);

+        

+        FooService fs = (FooService) getContext().getService(sr);

+        Properties toCheck = fs.fooProps();

+        

+        // Check service properties

+        Integer intProp = (Integer) toCheck.get("intProp");

+        Boolean boolProp = (Boolean) toCheck.get("boolProp");

+        String strProp = (String) toCheck.get("strProp");

+        String[] strAProp = (String[]) toCheck.get("strAProp");

+        int[] intAProp = (int[]) toCheck.get("intAProp");

+        

+        // Check updated

+        Integer updated = (Integer) toCheck.get("updated");

+        Dictionary dict = (Dictionary) toCheck.get("lastupdated");

+        

+        assertEquals("Check intProp equality", intProp, new Integer(0));

+        assertEquals("Check longProp equality", boolProp, new Boolean(false));

+        assertEquals("Check strProp equality", strProp, null);

+        assertNull("Check strAProp nullity", strAProp);

+        assertNull("Check intAProp  nullity", intAProp);

+        

+        assertEquals("updated count ", 1, updated.intValue());

+        assertEquals("Last update", 0, dict.size());

+       

+        assertTrue("invoke fs", fs.foo());

+        toCheck = fs.fooProps();

+        

+        // Re-check the property (change)

+        intProp = (Integer) toCheck.get("intProp");

+        boolProp = (Boolean) toCheck.get("boolProp");

+        strProp = (String) toCheck.get("strProp");

+        strAProp = (String[]) toCheck.get("strAProp");

+        intAProp = (int[]) toCheck.get("intAProp");

+        

+        updated = (Integer) toCheck.get("updated");

+        dict = (Dictionary) toCheck.get("lastupdated");

+        

+        assertEquals("Check intProp equality", intProp, new Integer(3));

+        assertEquals("Check longProp equality", boolProp, new Boolean(true));

+        assertEquals("Check strProp equality", strProp, new String("bar"));

+        assertNotNull("Check strAProp not nullity", strAProp);

+        String[] v = new String[] {"foo", "bar", "baz"};

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

+            if(!strAProp[i].equals(v[i])) { fail("Check the strAProp Equality"); }

+        }

+        assertNotNull("Check intAProp not nullity", intAProp);

+        int[] v2 = new int[] {3, 2, 1};

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

+            if(intAProp[i] != v2[i]) { fail("Check the intAProp Equality"); }

+        }

+        

+        fs = null;

+        getContext().ungetService(sr);   

+    }

+

+}

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java
new file mode 100644
index 0000000..c089ada
--- /dev/null
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedService.java
@@ -0,0 +1,280 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

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

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

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

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

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

+

+public class UpdatedMethodAndManagedService extends OSGiTestCase {

+

+	/**

+	 * Instance where the ManagedServicePID is provided by the component type. 

+	 */

+	ComponentInstance instance1;

+	/**

+     * Instance where the ManagedServicePID is provided by the instance. 

+     */

+	ComponentInstance instance2;

+	

+	/**

+     * Instance without configuration. 

+     */

+    ComponentInstance instance3;

+	

+	public void setUp() {

+	    String type = "CONFIG-FooProviderType-4Updated";

+        Properties p = new Properties();

+        p.put("instance.name","instance");

+        p.put("foo", "foo");

+        p.put("bar", "2");

+        p.put("baz", "baz");

+        instance1 = Utils.getComponentInstance(getContext(), type, p);

+        assertEquals("instance1 created", ComponentInstance.VALID,instance1.getState());

+        

+		type = "CONFIG-FooProviderType-3Updated";

+		Properties p1 = new Properties();

+		p1.put("instance.name","instance-2");

+		p1.put("foo", "foo");

+		p1.put("bar", "2");

+		p1.put("baz", "baz");

+		p1.put("managed.service.pid", "instance");

+		instance2 = Utils.getComponentInstance(getContext(), type, p1);

+		

+		type = "CONFIG-FooProviderType-3Updated";

+        Properties p2 = new Properties();

+        p2.put("instance.name","instance-3");

+        p2.put("managed.service.pid", "instance-3");

+        instance3 = Utils.getComponentInstance(getContext(), type, p2);

+	}

+	

+	public void tearDown() {

+		instance1.dispose();

+		instance2.dispose();

+		instance3.dispose();

+		instance1 = null;

+		instance2 = null;

+		instance3 = null;

+	}

+	

+	public void testStaticInstance1() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

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

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -1", fooP, "foo");

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

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

+				

+		ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "FooProvider-3");

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

+		

+		// Configuration of baz

+		Properties conf = new Properties();

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

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

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

+		ManagedService ms = (ManagedService) getContext().getService(msRef);

+		try {

+			ms.updated(conf);

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Re-check props

+		fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

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

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -2", fooP, "foo");

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

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

+		

+		// Get Service

+		FooService fs = (FooService) context.getService(fooRef);

+		Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+		

+        context.ungetService(fooRef);

+		getContext().ungetService(msRef);

+	}

+	

+	public void testStaticInstance2() {

+        ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check FS availability", fooRef);

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

+        Integer barP = (Integer) fooRef.getProperty("bar");

+        String bazP = (String) fooRef.getProperty("baz");

+        assertEquals("Check foo equality -1", fooP, "foo");

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

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

+        

+        ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "instance");

+        assertNotNull("Check ManagedService availability", msRef);

+        

+        

+        // Configuration of baz

+        Properties conf = new Properties();

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

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

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

+        ManagedService ms = (ManagedService) getContext().getService(msRef);

+        try {

+            ms.updated(conf);

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+        

+        // Recheck props

+        fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

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

+        barP = (Integer) fooRef.getProperty("bar");

+        bazP = (String) fooRef.getProperty("baz");

+        assertEquals("Check foo equality -2", fooP, "foo");

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

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

+        

+        // Get Service

+        FooService fs = (FooService) context.getService(fooRef);

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+        

+        getContext().ungetService(fooRef);

+        getContext().ungetService(msRef);

+    }

+	

+	public void testDynamicInstance1() {

+    	ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

+    	assertNotNull("Check FS availability", fooRef);

+    	

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

+    	Integer barP = (Integer) fooRef.getProperty("bar");

+    	String bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "foo");

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

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

+    	

+    	ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "FooProvider-3");

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

+    	

+    	// Configuration of baz

+    	Properties conf = new Properties();

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

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

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

+    	ManagedService ms = (ManagedService) getContext().getService(msRef);

+    	try {

+    		ms.updated(conf);

+    	} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+    	

+    	// Re-check props

+    	fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance1.getInstanceName());

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

+    	barP = (Integer) fooRef.getProperty("bar");

+    	bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "oof");

+    	assertEquals("Check bar equality", barP, new Integer(0));

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

+    	

+    	// Check field value

+    	FooService fs = (FooService) getContext().getService(fooRef);

+    	Properties p = fs.fooProps();

+    	fooP = (String) p.get("foo");

+    	barP = (Integer) p.get("bar");

+    	

+    	assertEquals("Check foo field equality", fooP, "oof");

+    	assertEquals("Check bar field equality", barP, new Integer(0));

+    	

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+    	

+    	getContext().ungetService(fooRef);

+    	getContext().ungetService(msRef);

+    }

+	

+	public void testDynamicInstance2() {

+        ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check FS availability", fooRef);

+        

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

+        Integer barP = (Integer) fooRef.getProperty("bar");

+        String bazP = (String) fooRef.getProperty("baz");

+        

+        assertEquals("Check foo equality", fooP, "foo");

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

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

+        

+        ServiceReference msRef = Utils.getServiceReferenceByPID(getContext(), ManagedService.class.getName(), "instance");

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

+        

+        // Configuration of baz

+        Properties conf = new Properties();

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

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

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

+        ManagedService ms = (ManagedService) getContext().getService(msRef);

+        try {

+            ms.updated(conf);

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+        

+        // Recheck props

+        fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

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

+        barP = (Integer) fooRef.getProperty("bar");

+        bazP = (String) fooRef.getProperty("baz");

+        

+        assertEquals("Check foo equality", fooP, "oof");

+        assertEquals("Check bar equality", barP, new Integer(0));

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

+        

+        // Check field value

+        FooService fs = (FooService) getContext().getService(fooRef);

+        Properties p = fs.fooProps();

+        fooP = (String) p.get("foo");

+        barP = (Integer) p.get("bar");

+        

+        assertEquals("Check foo field equality", fooP, "oof");

+        assertEquals("Check bar field equality", barP, new Integer(0));

+        

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size()); 

+        

+        getContext().ungetService(fooRef);

+        getContext().ungetService(msRef);

+    }

+}

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedServiceFactory.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedServiceFactory.java
new file mode 100644
index 0000000..4a8e5c1
--- /dev/null
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/UpdatedMethodAndManagedServiceFactory.java
@@ -0,0 +1,311 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.test.scenarios.configuration;

+

+import java.util.Dictionary;

+import java.util.Properties;

+

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

+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;

+import org.apache.felix.ipojo.test.scenarios.configuration.service.FooService;

+import org.apache.felix.ipojo.test.scenarios.util.Utils;

+import org.osgi.framework.ServiceReference;

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

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

+

+public class UpdatedMethodAndManagedServiceFactory extends OSGiTestCase {

+

+	ComponentInstance instance, instance2;

+	

+	public void setUp() {

+		String type = "CONFIG-FooProviderType-3Updated";

+		

+		Properties p1 = new Properties();

+		p1.put("instance.name","instance");

+		p1.put("foo", "foo");

+		p1.put("bar", "2");

+		p1.put("baz", "baz");

+		instance = Utils.getComponentInstance(getContext(), type, p1);

+		

+		Properties p2 = new Properties();

+        p2.put("instance.name","instance2");

+

+        instance2 = Utils.getComponentInstance(getContext(), type, p2);

+	}

+	

+	public void tearDown() {

+		instance.dispose();

+		instance2.dispose();

+		instance2 = null;

+		instance = null;

+	}

+	

+	public void testStatic() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

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

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -1", fooP, "foo");

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

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

+		

+		ServiceReference msRef = Utils.getServiceReferenceByName(getContext(), ManagedServiceFactory.class.getName(), instance.getFactory().getName());

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

+		

+		

+		// Configuration of baz

+		Properties conf = new Properties();

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

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

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

+		ManagedServiceFactory ms = (ManagedServiceFactory) getContext().getService(msRef);

+		try {

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

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Recheck props

+		fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

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

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		assertEquals("Check foo equality -2", fooP, "foo");

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

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

+		

+		 // Get Service

+        FooService fs = (FooService) context.getService(fooRef);

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+        

+		getContext().ungetService(msRef);

+	}

+	

+	public void testStaticNoValue() {

+        ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check FS availability", fooRef);

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

+        Object barP = fooRef.getProperty("bar");

+        Object bazP = fooRef.getProperty("baz");

+        assertEquals("Check foo equality -1", fooP, null);

+        assertEquals("Check bar equality -1", barP, null);

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

+        

+        ServiceReference msRef = Utils.getServiceReferenceByName(getContext(), ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

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

+        

+        

+        // Configuration of baz

+        Properties conf = new Properties();

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

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

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

+        ManagedServiceFactory ms = (ManagedServiceFactory) getContext().getService(msRef);

+        try {

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

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+        

+        // Recheck props

+        fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

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

+        barP = (Integer) fooRef.getProperty("bar");

+        bazP = (String) fooRef.getProperty("baz");

+        assertEquals("Check foo equality -2", fooP, "foo");

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

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

+        

+        // Get Service

+        FooService fs = (FooService) context.getService(fooRef);

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+        

+        getContext().ungetService(msRef);

+    }

+	

+	public void testDynamic() {

+    	ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

+    	assertNotNull("Check FS availability", fooRef);

+    	

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

+    	Integer barP = (Integer) fooRef.getProperty("bar");

+    	String bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "foo");

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

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

+    	

+    	ServiceReference msRef = Utils.getServiceReferenceByName(getContext(), ManagedServiceFactory.class.getName(), instance.getFactory().getName());

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

+    	

+    	// Configuration of baz

+    	Properties conf = new Properties();

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

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

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

+    	ManagedServiceFactory ms = (ManagedServiceFactory) getContext().getService(msRef);

+    	try {

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

+    	} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+    	

+    	// Recheck props

+    	fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

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

+    	barP = (Integer) fooRef.getProperty("bar");

+    	bazP = (String) fooRef.getProperty("baz");

+    	

+    	assertEquals("Check foo equality", fooP, "oof");

+    	assertEquals("Check bar equality", barP, new Integer(0));

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

+    	

+    	// Check field value

+    	FooService fs = (FooService) getContext().getService(fooRef);

+    	Properties p = fs.fooProps();

+    	fooP = (String) p.get("foo");

+    	barP = (Integer) p.get("bar");

+    	

+    	assertEquals("Check foo field equality", fooP, "oof");

+    	assertEquals("Check bar field equality", barP, new Integer(0));

+    	

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+    	

+    	getContext().ungetService(fooRef);

+    	getContext().ungetService(msRef);

+    }

+	

+	public void testDynamicNoValue() {

+        ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

+        assertNotNull("Check FS availability", fooRef);

+        

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

+        Object barP = fooRef.getProperty("bar");

+        Object bazP = fooRef.getProperty("baz");

+        assertEquals("Check foo equality -1", fooP, null);

+        assertEquals("Check bar equality -1", barP, null);

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

+        

+        ServiceReference msRef = Utils.getServiceReferenceByName(getContext(), ManagedServiceFactory.class.getName(), instance2.getFactory().getName());

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

+        

+        // Configuration of baz

+        Properties conf = new Properties();

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

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

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

+        ManagedServiceFactory ms = (ManagedServiceFactory) getContext().getService(msRef);

+        try {

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

+        } catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+        

+        // Recheck props

+        fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance2.getInstanceName());

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

+        barP = (Integer) fooRef.getProperty("bar");

+        bazP = (String) fooRef.getProperty("baz");

+        

+        assertEquals("Check foo equality", fooP, "oof");

+        assertEquals("Check bar equality", barP, new Integer(0));

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

+        

+        // Check field value

+        FooService fs = (FooService) getContext().getService(fooRef);

+        Properties p = fs.fooProps();

+        fooP = (String) p.get("foo");

+        barP = (Integer) p.get("bar");

+        

+        assertEquals("Check foo field equality", fooP, "oof");

+        assertEquals("Check bar field equality", barP, new Integer(0));

+        

+        Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+        

+        

+        getContext().ungetService(fooRef);

+        getContext().ungetService(msRef);

+    }

+

+

+    public void testDynamicString() {

+		ServiceReference fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

+		assertNotNull("Check FS availability", fooRef);

+		

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

+		Integer barP = (Integer) fooRef.getProperty("bar");

+		String bazP = (String) fooRef.getProperty("baz");

+		

+		assertEquals("Check foo equality", fooP, "foo");

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

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

+		

+		ServiceReference msRef = Utils.getServiceReferenceByName(getContext(), ManagedServiceFactory.class.getName(), instance.getFactory().getName());

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

+		

+		// Configuration of baz

+		Properties conf = new Properties();

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

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

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

+		ManagedServiceFactory ms = (ManagedServiceFactory) getContext().getService(msRef);

+		try {

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

+		} catch (ConfigurationException e) { fail("Configuration Exception : " + e); }

+		

+		// Recheck props

+		fooRef = Utils.getServiceReferenceByName(getContext(), FooService.class.getName(), instance.getInstanceName());

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

+		barP = (Integer) fooRef.getProperty("bar");

+		bazP = (String) fooRef.getProperty("baz");

+		

+		assertEquals("Check foo equality", fooP, "oof");

+		assertEquals("Check bar equality", barP, new Integer(0));

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

+		

+		// Check field value

+		FooService fs = (FooService) getContext().getService(fooRef);

+		Properties p = fs.fooProps();

+		fooP = (String) p.get("foo");

+		barP = (Integer) p.get("bar");

+		

+		assertEquals("Check foo field equality", fooP, "oof");

+		assertEquals("Check bar field equality", barP, new Integer(0));

+		

+		Integer updated = (Integer) fs.fooProps().get("updated");

+        Dictionary dict = (Dictionary) fs.fooProps().get("lastupdated");

+        

+        assertEquals("Check updated", 1, updated.intValue());

+        assertEquals("Check last updated", 2, dict.size());

+        

+		

+		getContext().ungetService(fooRef);

+		getContext().ungetService(msRef);

+	}

+

+}

diff --git a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java
index 055b9bd..ca53df4 100644
--- a/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java
+++ b/ipojo/tests/core/configuration/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java
@@ -79,7 +79,9 @@
             return fact.createComponentInstance(configuration);

         } catch (Exception e) {

             e.printStackTrace();

+          

             Assert.fail("Cannot create the instance from " + factoryName + " : " + e.getMessage());

+

             return null;

         }

         // }

diff --git a/ipojo/tests/core/configuration/src/main/resources/metadata.xml b/ipojo/tests/core/configuration/src/main/resources/metadata.xml
index 905b015..526dea9 100644
--- a/ipojo/tests/core/configuration/src/main/resources/metadata.xml
+++ b/ipojo/tests/core/configuration/src/main/resources/metadata.xml
@@ -248,4 +248,60 @@
 		</properties>

 	</component>

 	

+	<!--  updated -->

+	 <component

+		classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"

+		name="CONFIG-FooProviderType-ConfUpdated" architecture="true">

+		<provides />

+		<properties updated="updated">

+			<property name="int" field="intProp" value="2" />

+			<property name="boolean" field="boolProp" value="false" />

+			<property name="string" field="strProp" value="foo" />

+			<property name="strAProp" field="strAProp"

+				value="{foo, bar}" />

+			<property name="intAProp" field="intAProp" value="{1,2, 3}" />

+		</properties>

+	</component>

+	

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderTypeDyn"

+		name="CONFIG-FooProviderType-ConfNoValueUpdated" architecture="true">

+		<provides />

+		<properties updated="updated">

+			<property name="int" field="intProp"/>

+			<property name="boolean" field="boolProp"/>

+			<property name="string" field="strProp"/>

+			<property name="strAProp" field="strAProp"/>

+			<property name="intAProp" field="intAProp"/>

+		</properties>

+	</component>

+	

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		name="CONFIG-FooProviderType-4Updated" architecture="true">

+		<provides>

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+			<property name="baz" type="java.lang.String" />

+		</provides>

+		<properties propagation="true" pid="FooProvider-3" updated="updated">

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+		</properties>

+	</component>

+	

+	<component

+		classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType1"

+		name="CONFIG-FooProviderType-3Updated" architecture="true">

+		<provides>

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+			<property name="baz" type="java.lang.String" />

+		</provides>

+		<properties propagation="true" updated="updated">

+			<property name="foo" field="m_foo" />

+			<property name="bar" field="m_bar" />

+		</properties>

+	</component>

+	

 </ipojo>