diff --git a/ipojo/composite/NOTICE b/ipojo/composite/NOTICE
index ccfa91d..4216c02 100644
--- a/ipojo/composite/NOTICE
+++ b/ipojo/composite/NOTICE
@@ -15,7 +15,7 @@
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 This product uses software developed at
diff --git a/ipojo/core/NOTICE b/ipojo/core/NOTICE
index 5f3284c..6c6ecf8 100644
--- a/ipojo/core/NOTICE
+++ b/ipojo/core/NOTICE
@@ -9,14 +9,14 @@
 
 This product includes software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 II. Used Software
 
 This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+The OSGi Alliance (http://www.osgi.org).
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/ipojo/examples/junit4osgi/junit4osgi/pom.xml b/ipojo/examples/junit4osgi/junit4osgi/pom.xml
index 91f50d2..2496eab 100644
--- a/ipojo/examples/junit4osgi/junit4osgi/pom.xml
+++ b/ipojo/examples/junit4osgi/junit4osgi/pom.xml
@@ -65,7 +65,8 @@
 						</Bundle-SymbolicName>
 						<Private-Package>
 							org.apache.felix.ipojo.junit4osgi.impl,
-							org.apache.felix.ipojo.junit4osgi.test
+							org.apache.felix.ipojo.junit4osgi.test,
+							org.apache.felix.ipojo.junit4osgi.helpers
 						</Private-Package>
 						<Export-Package>
 							org.apache.felix.ipojo.junit4osgi, junit.*
diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java
index d4550c7..3f0d4ab 100644
--- a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/OSGiTestCase.java
@@ -1,187 +1,530 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.ipojo.junit4osgi;
-
-import junit.framework.TestCase;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * OSGi Test Case. Allow the injection of the bundle context.
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class OSGiTestCase extends TestCase {
-
-    protected BundleContext context;
-
-    public void setBundleContext(BundleContext bc) {
-        context = bc;
-    }
-
-    /**
-     * Asserts that two doubles are equal. If they are not an AssertionFailedError is thrown with the given message.
-     */
-    static public void assertEquals(String message, double expected, double actual) {
-        if (Double.compare(expected, actual) != 0) {
-            fail(formatEqualsMessage(message, new Double(expected), new Double(actual)));
-        }
-    }
-
-    static String formatEqualsMessage(String message, Object expected, Object actual) {
-        String formatted = "";
-        if (message != null) {
-            formatted = message + " ";
-        }
-        return formatted + "expected:<" + expected + "> but was:<" + actual + ">";
-    }
-
-    static String formatNotEqualsMessage(String message, Object o1, Object o2) {
-        String formatted = "";
-        if (message != null) {
-            formatted = message + " ";
-        }
-        return formatted + "o1:<" + o1 + "> is equals to o2:<" + o2 + ">";
-    }
-
-    static String formatContainsMessage(String message, Object[] array, Object txt) {
-        String formatted = "";
-        if (message != null) {
-            formatted = message + " ";
-        }
-
-        String arr = null;
-        for (int i = 0; i < array.length; i++) {
-            if (arr == null) {
-                arr = "[" + array[i];
-            } else {
-                arr += "," + array[i];
-            }
-        }
-        arr += "]";
-
-        return formatted + "array:" + arr + " does not contains:<" + txt + ">";
-    }
-
-    static public void assertNotEquals(String message, Object o1, Object o2) {
-        if (o1.equals(o2)) {
-            fail(formatNotEqualsMessage(message, o1, o2));
-        }
-    }
-
-    static public void assertContains(String message, String[] array, String txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i].equals(txt)) {
-                return;
-            }
-        }
-        fail(formatContainsMessage(message, array, txt));
-    }
-
-    static public void assertContains(String message, byte[] array, int txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Byte[] bytes = new Byte[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Byte(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Integer(txt)));
-    }
-
-    static public void assertContains(String message, short[] array, int txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Short[] bytes = new Short[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Short(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Integer(txt)));
-    }
-
-    static public void assertContains(String message, int[] array, int txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Integer[] bytes = new Integer[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Integer(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Integer(txt)));
-    }
-
-    static public void assertContains(String message, long[] array, long txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Long[] bytes = new Long[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Long(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Long(txt)));
-    }
-
-    static public void assertContains(String message, float[] array, float txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Float[] bytes = new Float[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Float(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Float(txt)));
-    }
-
-    static public void assertContains(String message, double[] array, double txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Double[] bytes = new Double[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Double(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Double(txt)));
-    }
-
-    static public void assertContains(String message, char[] array, char txt) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == txt) {
-                return;
-            }
-        }
-        Character[] bytes = new Character[array.length];
-        for (int i = 0; i < array.length; i++) {
-            bytes[i] = new Character(array[i]);
-        }
-        fail(formatContainsMessage(message, bytes, new Character(txt)));
-    }
-
-}
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.Factory;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * OSGi Test Case. Allow the injection of the bundle context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class OSGiTestCase extends TestCase {
+
+	protected BundleContext context;
+
+	public void setBundleContext(BundleContext bc) {
+		context = bc;
+	}
+	
+	public BundleContext getBundleContext() {
+	    return context;
+	}
+
+	public static void assertContains(String message, String[] array, String txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i].equals(txt)) {
+				return;
+			}
+		}
+		fail(formatContainsMessage(message, array, txt));
+	}
+
+	public static void assertContains(String message, byte[] array, int txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Byte[] bytes = new Byte[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Byte(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Integer(txt)));
+	}
+
+	public static void assertContains(String message, short[] array, int txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Short[] bytes = new Short[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Short(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Integer(txt)));
+	}
+
+	public static void assertContains(String message, int[] array, int txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Integer[] bytes = new Integer[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Integer(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Integer(txt)));
+	}
+
+	public static void assertContains(String message, long[] array, long txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Long[] bytes = new Long[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Long(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Long(txt)));
+	}
+
+	public static void assertContains(String message, float[] array, float txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Float[] bytes = new Float[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Float(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Float(txt)));
+	}
+
+	public static void assertContains(String message, double[] array, double txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Double[] bytes = new Double[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Double(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Double(txt)));
+	}
+
+	public static void assertContains(String message, char[] array, char txt) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == txt) {
+				return;
+			}
+		}
+		Character[] bytes = new Character[array.length];
+		for (int i = 0; i < array.length; i++) {
+			bytes[i] = new Character(array[i]);
+		}
+		fail(formatContainsMessage(message, bytes, new Character(txt)));
+	}
+
+	/**
+	 * Asserts that two doubles are equal. If they are not an
+	 * AssertionFailedError is thrown with the given message.
+	 */
+	public static void assertEquals(String message, double expected,
+			double actual) {
+		if (Double.compare(expected, actual) != 0) {
+			fail(formatEqualsMessage(message, new Double(expected), new Double(
+					actual)));
+		}
+	}
+
+	public static void assertNotEquals(String message, Object o1, Object o2) {
+		if (o1.equals(o2)) {
+			fail(formatNotEqualsMessage(message, o1, o2));
+		}
+	}
+
+	public static boolean contains(String string, String[] array) {
+		for (int i = 0; array != null && i < array.length; i++) {
+			if (array[i] != null && array[i].equals(string)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public static boolean contains(int value, int[] array) {
+		for (int i = 0; array != null && i < array.length; i++) {
+			if (array[i] == value) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	
+
+	private static String formatEqualsMessage(String message, Object expected,
+			Object actual) {
+		String formatted = "";
+		if (message != null) {
+			formatted = message + " ";
+		}
+		return formatted + "expected:<" + expected + "> but was:<" + actual
+				+ ">";
+	}
+
+	private static String formatNotEqualsMessage(String message, Object o1,
+			Object o2) {
+		String formatted = "";
+		if (message != null) {
+			formatted = message + " ";
+		}
+		return formatted + "o1:<" + o1 + "> is equals to o2:<" + o2 + ">";
+	}
+
+	private static String formatContainsMessage(String message, Object[] array,
+			Object txt) {
+		String formatted = "";
+		if (message != null) {
+			formatted = message + " ";
+		}
+
+		String arr = null;
+		for (int i = 0; i < array.length; i++) {
+			if (arr == null) {
+				arr = "[" + array[i];
+			} else {
+				arr += "," + array[i];
+			}
+		}
+		arr += "]";
+
+		return formatted + "array:" + arr + " does not contains:<" + txt + ">";
+	}
+
+	
+
+	/**
+	 * Returns the service object of a service provided by the specified bundle,
+	 * offering the specified interface and matching the given filter.
+	 * 
+	 * @param bundle
+	 *            the bundle in which the service is searched.
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return the service object provided by the specified bundle, offering the
+	 *         specified interface and matching the given filter.
+	 */
+	public static Object getServiceObject(Bundle bundle, String itf,
+			String filter) {
+		ServiceReference ref = getServiceReference(bundle, itf, filter);
+		if (ref != null) {
+			return bundle.getBundleContext().getService(ref);
+		} else {
+			return null;
+		}
+	}
+
+
+	/**
+	 * Returns the service objects of the services provided by the specified
+	 * bundle, offering the specified interface and matching the given filter.
+	 * 
+	 * @param bundle
+	 *            the bundle in which services are searched.
+	 * @param itf
+	 *            the interface provided by the searched services.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return the service objects provided by the specified bundle, offering
+	 *         the specified interface and matching the given filter.
+	 */
+	public static Object[] getServiceObjects(Bundle bundle, String itf,
+			String filter) {
+		ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+		if (refs != null) {
+			Object[] list = new Object[refs.length];
+			for (int i = 0; i < refs.length; i++) {
+				list[i] = bundle.getBundleContext().getService(refs[i]);
+			}
+			return list;
+		} else {
+			return new Object[0];
+		}
+	}
+
+
+
+	/**
+	 * Returns the service reference of a service provided by the specified
+	 * bundle, offering the specified interface and matching the given filter.
+	 * 
+	 * @param bundle
+	 *            the bundle in which the service is searched.
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return a service reference provided by the specified bundle, offering
+	 *         the specified interface and matching the given filter. If no
+	 *         service is found, {@code null} is returned.
+	 */
+	public static ServiceReference getServiceReference(Bundle bundle,
+			String itf, String filter) {
+		ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+		if (refs.length != 0) {
+			return refs[0];
+		} else {
+			// No service found
+			return null;
+		}
+	}
+	
+	/**
+	 * Checks if the service is available.
+	 * @param itf the service interface
+	 * @return <code>true</code> if the service is available,
+	 * <code>false</code> otherwise.
+	 */
+	public boolean isServiceAvailable(String itf) {
+        ServiceReference ref = getServiceReference(itf, null);
+        return ref != null;
+    }
+
+	/**
+     * Checks if the service is available.
+     * @param itf the service interface
+     * @param the service provider name
+     * @return <code>true</code> if the service is available,
+     * <code>false</code> otherwise.
+     */
+    public boolean isServiceAvailableByName(String itf, String name) {
+        ServiceReference ref = getServiceReferenceByName(itf, name);
+        return ref != null;
+    }
+    
+    /**
+     * Checks if the service is available.
+     * @param itf the service interface
+     * @param pid the service pid
+     * @return <code>true</code> if the service is available,
+     * <code>false</code> otherwise.
+     */
+    public boolean isServiceAvailableByPID(String itf, String pid) {
+        ServiceReference ref = getServiceReferenceByPID(itf, pid);
+        return ref != null;
+    }
+
+	
+
+	/**
+	 * Returns the service reference of the service provided by the specified
+	 * bundle, offering the specified interface and having the given persistent
+	 * ID.
+	 * 
+	 * @param bundle
+	 *            the bundle in which the service is searched.
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param pid
+	 *            the persistent ID of the searched service.
+	 * @return a service provided by the specified bundle, offering the
+	 *         specified interface and having the given persistent ID.
+	 */
+	public static ServiceReference getServiceReferenceByPID(Bundle bundle,
+			String itf, String pid) {
+		String filter = "(" + "service.pid" + "=" + pid + ")";
+		ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+		if (refs == null) {
+			return null;
+		} else if (refs.length == 1) {
+			return refs[0];
+		} else {
+			throw new IllegalStateException(
+					"A service lookup by PID returned several providers ("
+							+ refs.length + ")" + " for " + itf + " with pid="
+							+ pid);
+		}
+	}
+
+	
+
+	/**
+	 * Returns the service reference of a service provided by the specified
+	 * bundle, offering the specified interface and having the given name.
+	 * 
+	 * @param bundle
+	 *            the bundle in which the service is searched.
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param name
+	 *            the name of the searched service.
+	 * @return a service provided by the specified bundle, offering the
+	 *         specified interface and having the given name.
+	 */
+	public static ServiceReference getServiceReferenceByName(Bundle bundle,
+			String itf, String name) {
+		String filter = null;
+		if (itf.equals(Factory.class.getName())
+				|| itf.equals(ManagedServiceFactory.class.getName())) {
+			filter = "(" + "factory.name" + "=" + name + ")";
+		} else {
+			filter = "(" + "instance.name" + "=" + name + ")";
+		}
+		return getServiceReference(bundle, itf, filter);
+	}
+
+	
+
+	/**
+	 * Returns the service reference of all the services provided in the
+	 * specified bundle, offering the specified interface and matching the given
+	 * filter.
+	 * 
+	 * @param bundle
+	 *            the bundle in which services are searched.
+	 * @param itf
+	 *            the interface provided by the searched services.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return all the service references provided in the specified bundle,
+	 *         offering the specified interface and matching the given filter.
+	 *         If no service matches, an empty array is returned.
+	 */
+	public static ServiceReference[] getServiceReferences(Bundle bundle,
+			String itf, String filter) {
+		ServiceReference[] refs = null;
+		try {
+			// Get all the service references
+			refs = bundle.getBundleContext().getServiceReferences(itf, filter);
+		} catch (InvalidSyntaxException e) {
+			throw new IllegalArgumentException(
+					"Cannot get service references.", e);
+		}
+		if (refs == null) {
+			return new ServiceReference[0];
+		} else {
+			return refs;
+		}
+	}
+
+	
+	
+	/**
+	 * Returns the service object of a service provided by the local bundle,
+	 * offering the specified interface and matching the given filter.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return the service object provided by the local bundle, offering the
+	 *         specified interface and matching the given filter.
+	 */
+	public Object getServiceObject(String itf, String filter) {
+		return getServiceObject(context.getBundle(), itf, filter);
+	}
+
+	/**
+	 * Returns the service objects of the services provided by the local
+	 * bundle, offering the specified interface and matching the given filter.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched services.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return the service objects provided by the local bundle, offering
+	 *         the specified interface and matching the given filter.
+	 */
+	public Object[] getServiceObjects(String itf, String filter) {
+		return getServiceObjects(context.getBundle(), itf, filter);
+	}
+
+	/**
+	 * Returns the service reference of a service provided by the local
+	 * bundle, offering the specified interface and matching the given filter.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return a service reference provided by the local bundle, offering
+	 *         the specified interface and matching the given filter. If no
+	 *         service is found, {@code null} is returned.
+	 */
+	public ServiceReference getServiceReference(String itf, String filter) {
+		return getServiceReference(context.getBundle(), itf, filter);
+	}
+
+	/**
+	 * Returns the service reference of the service provided by the local
+	 * bundle, offering the specified interface and having the given persistent
+	 * ID.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param pid
+	 *            the persistent ID of the searched service.
+	 * @return a service provided by the local bundle, offering the
+	 *         specified interface and having the given persistent ID.
+	 */
+	public ServiceReference getServiceReferenceByPID(String itf, String pid) {
+		return getServiceReferenceByPID(context.getBundle(), itf, pid);
+	}
+
+	/**
+	 * Returns the service reference of a service provided by the local
+	 * bundle, offering the specified interface and having the given name.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched service.
+	 * @param name
+	 *            the name of the searched service.
+	 * @return a service provided by the specified bundle, offering the
+	 *         specified interface and having the given name.
+	 */
+	public ServiceReference getServiceReferenceByName(String itf, String name) {
+		return getServiceReferenceByName(context.getBundle(), itf, name);
+	}
+
+	/**
+	 * Returns the service reference of all the services provided in the
+	 * local bundle, offering the specified interface and matching the given
+	 * filter.
+	 * 
+	 * @param itf
+	 *            the interface provided by the searched services.
+	 * @param filter
+	 *            an additional filter (can be {@code null}).
+	 * @return all the service references provided in the local bundle,
+	 *         offering the specified interface and matching the given filter.
+	 *         If no service matches, an empty array is returned.
+	 */
+	public ServiceReference[] getServiceReferences(String itf, String filter) {
+		return getServiceReferences(context.getBundle(), itf, filter);
+	}
+	
+	
+
+}
diff --git a/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/helpers/IPOJOHelper.java b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/helpers/IPOJOHelper.java
new file mode 100644
index 0000000..7d08dea
--- /dev/null
+++ b/ipojo/examples/junit4osgi/junit4osgi/src/main/java/org/apache/felix/ipojo/junit4osgi/helpers/IPOJOHelper.java
@@ -0,0 +1,663 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.junit4osgi.helpers;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+public class IPOJOHelper {
+    
+    private BundleContext context;
+    private OSGiTestCase testcase;
+    
+    public IPOJOHelper(OSGiTestCase tc) {
+        testcase = tc;
+        context = testcase.getBundleContext();
+    }
+    
+    /**
+     * Creates a new component instance with the given name (and empty
+     * configuration), from the factory specified in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component factory is defined.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            bundle.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, String instanceName) {
+
+        // Create the instance configuration
+        Properties configuration = new Properties();
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(bundle, factoryName, configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given configuration, from the
+     * factory specified in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component factory is defined.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            bundle.
+     * @param configuration
+     *            the configuration of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, Dictionary configuration) {
+
+        // Retrieve the component factory.
+        Factory fact = getFactory(bundle, factoryName);
+
+        if (fact == null) {
+            // Factory not found...
+            throw new IllegalArgumentException(
+                    "Cannot find the component factory (" + factoryName
+                            + ") in the specified bundle ("
+                            + bundle.getSymbolicName() + ").");
+        }
+
+        try {
+            return fact.createComponentInstance(configuration);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "Cannot create the component instance with the given configuration.",
+                    e);
+        }
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component factory is defined.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            bundle.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @param configuration
+     *            the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, String instanceName, Dictionary configuration) {
+
+        // Add the instance name to the configuration
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(bundle, factoryName, configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name (and an empty
+     * configuration), from the factory specified in the given service context.
+     * 
+     * @param serviceContext
+     *            the service context in which the component factory service is
+     *            registered.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            service context.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            String instanceName) {
+
+        // Create the instance configuration
+        Properties configuration = new Properties();
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(serviceContext, factoryName,
+                configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given service context.
+     * 
+     * @param serviceContext
+     *            the service context in which the component factory service is
+     *            registered.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            service context.
+     * @param configuration
+     *            the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            Dictionary configuration) {
+
+        // Retrieve the component factory.
+        Factory fact = getFactory(serviceContext, factoryName);
+
+        if (fact == null) {
+            // Factory not found...
+            throw new IllegalArgumentException(
+                    "Cannot find the component factory (" + factoryName
+                            + ") in the specified service context.");
+        }
+
+        try {
+            return fact.createComponentInstance(configuration);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "Cannot create the component instance with the given configuration.",
+                    e);
+        }
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given service context.
+     * 
+     * @param serviceContext
+     *            the service context in which the component factory service is
+     *            registered.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            service context.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @param configuration
+     *            the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            String instanceName, Dictionary configuration) {
+
+        // Add the instance name to the configuration
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(serviceContext, factoryName,
+                configuration);
+    }
+    
+    /**
+     * Creates a new component instance with the given name (and empty
+     * configuration), from the factory specified in the local bundle.
+     * 
+     * @param factoryName
+     *            the name of the component factory, defined in the local
+     *            bundle.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            String instanceName) {
+        return createComponentInstance(context.getBundle(), factoryName,
+                instanceName);
+    }
+
+    /**
+     * Creates a new component instance with the given configuration, from the
+     * factory specified in the local bundle.
+     * 
+     * @param factoryName
+     *            the name of the component factory, in the local bundle.
+     * @param configuration
+     *            the configuration of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            Dictionary configuration) {
+        return createComponentInstance(context.getBundle(), factoryName,
+                configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component factory is defined.
+     * @param factoryName
+     *            the name of the component factory, defined in the specified
+     *            bundle.
+     * @param instanceName
+     *            the name of the component instance to create.
+     * @param configuration
+     *            the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            String instanceName, Dictionary configuration) {
+        return createComponentInstance(context.getBundle(), factoryName,
+                instanceName, configuration);
+    }
+
+    /**
+     * Returns the component factory with the given name in the local bundle.
+     * 
+     * @param factoryName
+     *            the name of the factory to retrieve.
+     * @return the component factory with the given name in the local bundle, or
+     *         {@code null} if not found.
+     */
+    public Factory getFactory(String factoryName) {
+        return getFactory(context.getBundle(), factoryName);
+    }
+
+    /**
+     * Returns the handler factory with the given name in the local bundle.
+     * 
+     * @param factoryName
+     *            the name of the handler factory to retrieve.
+     * @return the handler factory with the given name in the local bundle, or
+     *         {@code null} if not found.
+     */
+    public HandlerFactory getHandlerFactory(String factoryName) {
+        return getHandlerFactory(context.getBundle(), factoryName);
+    }
+
+    /**
+     * Returns the metadata description of the component defined in this bundle.
+     * 
+     * @param component
+     *            the name of the locally defined component.
+     * @return the metadata description of the component with the given name,
+     *         defined in this given bundle, or {@code null} if not found.
+     */
+    public Element getMetadata(String component) {
+        return getMetadata(context.getBundle(), component);
+    }
+    
+    /**
+     * Returns the component factory with the given name in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component factory is defined.
+     * @param factoryName
+     *            the name of the defined factory.
+     * @return the component factory with the given name in the given bundle, or
+     *         {@code null} if not found.
+     */
+    public static Factory getFactory(Bundle bundle, String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the component factories services in the bundle.
+            refs = bundle.getBundleContext().getServiceReferences(
+                    Factory.class.getName(),
+                    "(factory.name=" + factoryName + ")");
+            if (refs != null) {
+                return ((Factory) bundle.getBundleContext().getService(refs[0]));
+            }
+
+            // Factory not found...
+            return null;
+
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get the component factory services.", e);
+        }
+    }
+
+    /**
+     * Returns the component factory with the given name, registered in the
+     * given service context.
+     * 
+     * @param serviceContext
+     *            the service context in which the factory service is defined.
+     * @param factoryName
+     *            the name of the factory.
+     * @return the component factory with the given name, registered in the
+     *         given service context.
+     */
+    public static Factory getFactory(ServiceContext serviceContext,
+            String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the component factories services in the service
+            // context.
+            refs = serviceContext.getServiceReferences(Factory.class.getName(),
+                    "(factory.name=" + factoryName + ")");
+            if (refs != null) {
+                return ((Factory) serviceContext.getService(refs[0]));
+            }
+            return null;
+
+        } catch (InvalidSyntaxException e) {
+            System.err.println("Cannot get the factory " + factoryName + " : "
+                    + e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Returns the handler factory with the given name in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the handler factory is defined.
+     * @param factoryName
+     *            the name of the handler factory to retrieve.
+     * @return the handler factory with the given name in the given bundle, or
+     *         {@code null} if not found.
+     */
+    public static HandlerFactory getHandlerFactory(Bundle bundle,
+            String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the handler factories services in the bundle.
+            refs = bundle.getBundleContext().getServiceReferences(
+                    HandlerFactory.class.getName(),
+                    "(" + Handler.HANDLER_NAME_PROPERTY + "=" + factoryName
+                            + ")");
+            if (refs != null) {
+                return (HandlerFactory) bundle.getBundleContext().getService(
+                        refs[0]);
+            }
+
+            // Factory not found...
+            return null;
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get the handler factory services.", e);
+        }
+    }
+
+    /**
+     * Returns the metadata description of the component with the given name,
+     * defined in the given bundle.
+     * 
+     * @param bundle
+     *            the bundle in which the component is defined.
+     * @param component
+     *            the name of the defined component.
+     * @return the metadata description of the component with the given name,
+     *         defined in the given bundle, or {@code null} if not found.
+     */
+    public static Element getMetadata(Bundle bundle, String component) {
+
+        // Retrieves the component description from the bundle's manifest.
+        String elem = (String) bundle.getHeaders().get("iPOJO-Components");
+        if (elem == null) {
+            throw new IllegalArgumentException(
+                    "Cannot find iPOJO-Components descriptor in the specified bundle ("
+                            + bundle.getSymbolicName()
+                            + "). Not an iPOJO bundle.");
+        }
+
+        // Parses the retrieved description and find the component with the
+        // given name.
+        try {
+            Element element = ManifestMetadataParser.parseHeaderMetadata(elem);
+            Element[] childs = element.getElements("component");
+            for (int i = 0; i < childs.length; i++) {
+                String name = childs[i].getAttribute("name");
+                String clazz = childs[i].getAttribute("classname");
+                if (name != null && name.equalsIgnoreCase(component)) {
+                    return childs[i];
+                }
+                if (clazz.equalsIgnoreCase(component)) {
+                    return childs[i];
+                }
+            }
+
+            // Component not found...
+            return null;
+
+        } catch (ParseException e) {
+            throw new IllegalStateException(
+                    "Cannot parse the components from specified bundle ("
+                            + bundle.getSymbolicName() + ").", e);
+        }
+    }
+    
+    /**
+     * Returns the service object of a service registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext
+     *            the service context in which the service is searched.
+     * @param itf
+     *            the interface provided by the searched service.
+     * @param filter
+     *            an additional filter (can be {@code null}).
+     * @return the service object provided by the specified bundle, offering the
+     *         specified interface and matching the given filter.
+     */
+    public static Object getServiceObject(ServiceContext serviceContext,
+            String itf, String filter) {
+        ServiceReference ref = getServiceReference(serviceContext, itf, filter);
+        if (ref != null) {
+            return serviceContext.getService(ref);
+        } else {
+            return null;
+        }
+    }
+    
+    /**
+     * Returns the service objects of the services registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext
+     *            the service context in which services are searched.
+     * @param itf
+     *            the interface provided by the searched services.
+     * @param filter
+     *            an additional filter (can be {@code null}).
+     * @return the service objects provided by the specified bundle, offering
+     *         the specified interface and matching the given filter.
+     */
+    public static Object[] getServiceObjects(ServiceContext serviceContext,
+            String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs != null) {
+            Object[] list = new Object[refs.length];
+            for (int i = 0; i < refs.length; i++) {
+                list[i] = serviceContext.getService(refs[i]);
+            }
+            return list;
+        } else {
+            return new Object[0];
+        }
+    }
+    
+    /**
+     * Returns the service reference of a service registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext
+     *            the service context in which services are searched.
+     * @param itf
+     *            the interface provided by the searched service.
+     * @param filter
+     *            an additional filter (can be {@code null}).
+     * @return a service reference registered in the specified service context,
+     *         offering the specified interface and matching the given filter.
+     *         If no service is found, {@code null} is returned.
+     */
+    public static ServiceReference getServiceReference(
+            ServiceContext serviceContext, String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs.length != 0) {
+            return refs[0];
+        } else {
+            // No service found
+            return null;
+        }
+    }
+    
+    /**
+     * Returns the service reference of the service registered in the specified
+     * service context, offering the specified interface and having the given
+     * persistent ID.
+     * 
+     * @param serviceContext
+     *            the service context in which services are searched.
+     * @param itf
+     *            the interface provided by the searched service.
+     * @param pid
+     *            the persistent ID of the searched service.
+     * @return a service registered in the specified service context, offering
+     *         the specified interface and having the given persistent ID.
+     */
+    public static ServiceReference getServiceReferenceByPID(
+            ServiceContext serviceContext, String itf, String pid) {
+        String filter = "(" + "service.pid" + "=" + pid + ")";
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs == null) {
+            return null;
+        } else if (refs.length == 1) {
+            return refs[0];
+        } else {
+            throw new IllegalStateException(
+                    "A service lookup by PID returned several providers ("
+                            + refs.length + ")" + " for " + itf + " with pid="
+                            + pid);
+        }
+    }
+    
+    /**
+     * Returns the service reference of all the services registered in the
+     * specified service context, offering the specified interface and matching
+     * the given filter.
+     * 
+     * @param serviceContext
+     *            the service context in which services are searched.
+     * @param itf
+     *            the interface provided by the searched services.
+     * @param filter
+     *            an additional filter (can be {@code null}).
+     * @return all the service references registered in the specified service
+     *         context, offering the specified interface and matching the given
+     *         filter. If no service matches, an empty array is returned.
+     */
+    public static ServiceReference[] getServiceReferences(
+            ServiceContext serviceContext, String itf, String filter) {
+        ServiceReference[] refs = null;
+        try {
+            // Get all the service references
+            refs = serviceContext.getServiceReferences(itf, filter);
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get service references.", e);
+        }
+        if (refs == null) {
+            return new ServiceReference[0];
+        } else {
+            return refs;
+        }
+    }
+
+    
+    /**
+     * Returns the service reference of a service registered in the specified
+     * service context, offering the specified interface and having the given
+     * name.
+     * 
+     * @param serviceContext
+     *            the service context in which services are searched.
+     * @param itf
+     *            the interface provided by the searched service.
+     * @param name
+     *            the name of the searched service.
+     * @return a service registered in the specified service context, offering
+     *         the specified interface and having the given name.
+     */
+    public static ServiceReference getServiceReferenceByName(
+            ServiceContext serviceContext, String itf, String name) {
+        String filter = null;
+        if (itf.equals(Factory.class.getName())
+                || itf.equals(ManagedServiceFactory.class.getName())) {
+            filter = "(" + "factory.name" + "=" + name + ")";
+        } else {
+            filter = "(" + "instance.name" + "=" + name + ")";
+        }
+        return getServiceReference(serviceContext, itf, filter);
+    }
+    
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @return <code>true</code> if the service is available in the service
+     * context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailable(ServiceContext sc, String itf) {
+        ServiceReference ref = getServiceReference(sc, itf, null);
+        return ref != null;
+    }
+
+    
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @param name the service provider name
+     * @return <code>true</code> if the service is available in the service
+     * context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailableByName(ServiceContext sc, String itf, String name) {
+        ServiceReference ref = getServiceReferenceByName(sc, itf, name);
+        return ref != null;
+    }
+    
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @param pid the pid of the service
+     * @return <code>true</code> if the service is available in the service
+     * context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailableByPID(ServiceContext sc, String itf, String pid) {
+        ServiceReference ref = getServiceReferenceByPID(sc, itf, pid);
+        return ref != null;
+    }
+    
+
+}
diff --git a/ipojo/handler/eventadmin/NOTICE b/ipojo/handler/eventadmin/NOTICE
index ceb3d18..f221cb6 100644
--- a/ipojo/handler/eventadmin/NOTICE
+++ b/ipojo/handler/eventadmin/NOTICE
@@ -7,16 +7,11 @@
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
-Licensed under the Apache License 2.0.
-
 II. Used Software
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/ipojo/handler/extender/NOTICE b/ipojo/handler/extender/NOTICE
index f80d474..652b572 100644
--- a/ipojo/handler/extender/NOTICE
+++ b/ipojo/handler/extender/NOTICE
@@ -7,16 +7,11 @@
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
-Licensed under the Apache License 2.0.
-
 II. Used Software
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/ipojo/handler/jmx/NOTICE b/ipojo/handler/jmx/NOTICE
index aba3d8f..e949939 100644
--- a/ipojo/handler/jmx/NOTICE
+++ b/ipojo/handler/jmx/NOTICE
@@ -11,7 +11,7 @@
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/ipojo/handler/temporal/NOTICE b/ipojo/handler/temporal/NOTICE
index a10772b..730aad5 100644
--- a/ipojo/handler/temporal/NOTICE
+++ b/ipojo/handler/temporal/NOTICE
@@ -11,7 +11,7 @@
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000, 2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/ipojo/handler/whiteboard/NOTICE b/ipojo/handler/whiteboard/NOTICE
index d7d7486..26a4074 100644
--- a/ipojo/handler/whiteboard/NOTICE
+++ b/ipojo/handler/whiteboard/NOTICE
@@ -1,4 +1,4 @@
-Apache Felix iPOJO White-board Pattern Handler
+Apache Felix iPOJO Whiteboard Pattern Handler
 Copyright 2008 The Apache Software Foundation
 
 I. Included Software
@@ -7,16 +7,11 @@
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
-Licensed under the Apache License 2.0.
-
 II. Used Software
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright 2006 The OSGi Alliance.
+Copyright (c) OSGi Alliance (2000,2007).
 Licensed under the Apache License 2.0.
 
 III. License Summary
