FELIX-3903 - Restructuration of the event admin handler project and migration of the tests to pax exam 3

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1450816 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/pom.xml b/ipojo/handler/eventadmin/eventadmin-handler-it/pom.xml
new file mode 100644
index 0000000..86e2c3e
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/pom.xml
@@ -0,0 +1,344 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>pom</packaging>
+    <groupId>org.apache.felix</groupId>
+    <name>Apache Felix iPOJO Event Admin Handler - Integration Test</name>
+    <artifactId>org.apache.felix.ipojo.handler.eventadmin-it</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+
+    <properties>
+        <exam.version>3.0.0</exam.version>
+        <url.version>1.5.1</url.version>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.ipojo.handler.eventadmin</artifactId>
+            <version>${project.version}</version>
+            <!--
+             The event admin handler depends on an older version of the compendium and core, to avoid issue during
+             tests, we must exclude those artifacts and trust the framework to provide the right / compatible
+              version
+            -->
+            <exclusions>
+                <exclusion>
+                    <groupId>org.osgi</groupId>
+                    <artifactId>org.osgi.compendium</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.osgi</groupId>
+                    <artifactId>org.osgi.core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>org.apache.felix.ipojo</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.framework</artifactId>
+            <version>4.2.0</version>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.ipojo</artifactId>
+            <version>1.8.6</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-native</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-link-mvn</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-aether</artifactId>
+            <version>${url.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>0.9.20</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>0.9.20</version>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.ops4j.pax.tinybundles</groupId>
+            <artifactId>tinybundles</artifactId>
+            <version>1.0.0</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ow2.chameleon.testing</groupId>
+            <artifactId>osgi-helpers</artifactId>
+            <version>0.6.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ow2.chameleon.testing</groupId>
+            <artifactId>tinybundles-ipojo</artifactId>
+            <version>0.3.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-wrap</artifactId>
+            <version>1.5.2</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.servicemix.tooling</groupId>
+                <artifactId>depends-maven-plugin</artifactId>
+                <version>1.2</version>
+                <executions>
+                    <execution>
+                        <id>generate-config</id>
+                        <goals>
+                            <goal>generate-depends-file</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.5.1</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>test</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-invoker-plugin</artifactId>
+                        <version>1.8</version>
+                        <configuration>
+                            <streamLogs>true</streamLogs>
+                            <goals>
+                                <goal>clean</goal>
+                                <goal>test</goal>
+                            </goals>
+                            <cloneClean>true</cloneClean>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>regular</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>felix</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/regular</cloneProjectsTo>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>test-all</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-invoker-plugin</artifactId>
+                        <version>1.8</version>
+                        <configuration>
+                            <streamLogs>true</streamLogs>
+                            <goals>
+                                <goal>clean</goal>
+                                <goal>test</goal>
+                            </goals>
+                            <cloneClean>true</cloneClean>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>equinox-native</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>equinox</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/equinox-native</cloneProjectsTo>
+
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>felix-native</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>felix</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/felix-native</cloneProjectsTo>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>knopflerfish</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>pax.exam.framework</name>
+                    <value>knopflerfish</value>
+                </property>
+            </activation>
+            <properties>
+                <pax.exam.framework>knopflerfish</pax.exam.framework>
+            </properties>
+            <repositories>
+                <repository>
+                    <id>knopflerfish-releases</id>
+                    <url>http://www.knopflerfish.org/maven2</url>
+                </repository>
+            </repositories>
+            <dependencies>
+                <dependency>
+                    <groupId>org.knopflerfish</groupId>
+                    <artifactId>framework</artifactId>
+                    <version>5.2.0</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <id>equinox</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>pax.exam.framework</name>
+                    <value>equinox</value>
+                </property>
+            </activation>
+            <properties>
+                <pax.exam.framework>equinox</pax.exam.framework>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.eclipse.tycho</groupId>
+                    <artifactId>org.eclipse.osgi</artifactId>
+                    <version>3.8.1.v20120830-144521</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <id>felix</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>pax.exam.framework</name>
+                    <value>felix</value>
+                </property>
+            </activation>
+            <properties>
+                <pax.exam.framework>felix</pax.exam.framework>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>org.apache.felix.framework</artifactId>
+                    <version>4.2.0</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+    </profiles>
+</project>
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/ipojo-event-admin-integration-test.iml b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/ipojo-event-admin-integration-test.iml
new file mode 100644
index 0000000..de1441f
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/ipojo-event-admin-integration-test.iml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.ipojo.handler.eventadmin:@project.version@" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.exam:pax-exam-container-native:3.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.exam:pax-exam:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-lang:1.3.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-store:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-io:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-monitors:1.3.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-util-property:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.exam:pax-exam-spi:3.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.base:ops4j-base-spi:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.guava:guava:12.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.pax.tinybundles:tinybundles:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: biz.aQute:bndlib:1.43.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.glassfish.main.common:scattered-archive-api:3.1.2.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-core:1.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-lifecycle:1.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-tracker:1.6.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.base:ops4j-base-net:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.url:pax-url-link:1.5.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.pax.url:pax-url-commons:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-property:1.5.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.url:pax-url-classpath:1.5.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-optional-jcl:1.5.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.exam:pax-exam-junit4:3.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.exam:pax-exam-link-mvn:3.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.url:pax-url-aether:1.5.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.pax.url:pax-url-maven-commons:1.5.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.base:ops4j-base-util-xml:1.3.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ops4j.base:ops4j-base-util-collections:1.3.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.aether:aether-api:1.13.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.aether:aether-spi:1.13.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.aether:aether-util:1.13.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.aether:aether-impl:1.13.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.aether:aether-connector-wagon:1.13.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven.wagon:wagon-provider-api:1.0-beta-7" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-utils:3.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-classworlds:2.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.sisu:sisu-inject-plexus:2.2.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-component-annotations:1.5.5" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.sisu:sisu-inject-bean:2.2.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.sonatype.sisu:sisu-guice:no_aop:3.0.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven:maven-aether-provider:3.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven:maven-model:3.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven:maven-model-builder:3.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-interpolation:1.14" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven:maven-repository-metadata:3.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven.wagon:wagon-file:1.0-beta-7" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-7" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.maven.wagon:wagon-http-shared:1.0-beta-7" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-container-default:1.5.5" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.xbean:xbean-reflect:3.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.collections:google-collections:1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: commons-codec:commons-codec:1.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.felix:org.apache.felix.framework:4.2.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: ch.qos.logback:logback-core:0.9.6" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: ch.qos.logback:logback-classic:0.9.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mockito:mockito-all:1.9.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.ipojo:1.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.osgi:org.osgi.core:4.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.osgi:org.osgi.compendium:4.0.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.ipojo.metadata:1.6.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.ipojo.manipulator:1.8.6" level="project" />
+    <orderEntry type="library" name="Maven: asm:asm-all:3.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.felix:org.apache.felix.ipojo.annotations:1.8.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.felix:org.apache.felix.configadmin:1.6.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.ow2.chameleon.testing:osgi-helpers:0.6.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ow2.chameleon.testing:tinybundles-ipojo:0.3.0" level="project" />
+    <orderEntry type="library" name="Maven: xerces:xercesImpl:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.pax.url:pax-url-wrap:1.5.2" level="project" />
+    <orderEntry type="library" name="Maven: org.ops4j.pax.swissbox:pax-swissbox-bnd:1.5.0" level="project" />
+  </component>
+</module>
+
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/pom.xml b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/pom.xml
new file mode 100644
index 0000000..4798e76
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.ipojo.handler.eventadmin-it</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+
+
+    <artifactId>ipojo-event-admin-integration-test</artifactId>
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/AsyncEventProviderImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/AsyncEventProviderImpl.java
new file mode 100644
index 0000000..bb023f8
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/AsyncEventProviderImpl.java
@@ -0,0 +1,74 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+import org.osgi.service.event.EventAdmin;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+import java.util.Random;

+

+/**

+ * Implementation of an event vendor that directly uses the Event Admin service

+ * to post (asynchronously) raw events.

+ *

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

+ */

+public class AsyncEventProviderImpl implements DonutProvider {

+

+    /**

+     * The donut current serial number.

+     */

+    private long m_serial = 0L;

+    /**

+     * The name of the donut vendor.

+     */

+    private String m_name;

+    /**

+     * A random generator.

+     */

+    private Random m_random;

+    /**

+     * The Event Admin service reference.

+     */

+    private EventAdmin m_ea;

+

+    /**

+     * Construct a new donut provider. The initial serial number is randomly

+     * generated.

+     */

+    public AsyncEventProviderImpl() {

+        m_random = new Random(System.currentTimeMillis());

+    }

+

+    /**

+     * Sell a donut with a random flavour.

+     *

+     * @return the sold donut

+     */

+    public Donut sellDonut() {

+        Dictionary rawEvent = new Hashtable();

+        Donut donut = new Donut(m_serial++, m_name, Donut.FLAVOURS[m_random

+                .nextInt(Donut.FLAVOURS.length)]);

+        rawEvent.put("food", donut);

+        m_ea.postEvent(new Event("food/donuts", rawEvent));

+        return donut;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/Donut.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/Donut.java
new file mode 100644
index 0000000..c848adc
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/Donut.java
@@ -0,0 +1,100 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+/**

+ * Donut representation.

+ * 

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

+ */

+public class Donut {

+

+    /**

+     * All possible donut flavours.

+     */

+    public static final String[] FLAVOURS = { "unflavoured", "icing sugar",

+        "chocolate", "toffee", "strawberry", "apple" };

+

+    /**

+     * The vendor's unique donut identifier.

+     */

+    private final long m_id;

+

+    /**

+     * The name of this donut's vendor.

+     */

+    private final String m_vendorName;

+

+    /**

+     * The m_flavour of this donut.

+     */

+    private final String m_flavour;

+

+    /**

+     * Create a new donut.

+     * 

+     * @param id

+     *            the vendor's unique donut identifier

+     * @param vendorName

+     *            the name of this donut's vendor

+     * @param flavour

+     *            the m_flavour of this donut

+     */

+    public Donut(long id, String vendorName, String flavour) {

+        this.m_id = id;

+        this.m_vendorName = vendorName;

+        this.m_flavour = flavour;

+    }

+

+    /**

+     * Get the vendor's unique identifier of this donut.

+     * 

+     * @return the id

+     */

+    public long getId() {

+        return m_id;

+    }

+

+    /**

+     * Get the vendor name of this donut.

+     * 

+     * @return the name

+     */

+    public String getVendorName() {

+        return m_vendorName;

+    }

+

+    /**

+     * Get the flavour of this donut.

+     * 

+     * @return the flavour

+     */

+    public String getFlavour() {

+        return m_flavour;

+    }

+

+    /**

+     * Return the string representation of this donut.

+     * 

+     * @return this donut as a String

+     */

+    public String toString() {

+        return m_id + " " + m_flavour + " (" + m_vendorName + ")";

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumer.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumer.java
new file mode 100644
index 0000000..7482ff6
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumer.java
@@ -0,0 +1,81 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+

+/**

+ * Specification of a donut consumer.

+ * 

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

+ */

+public interface DonutConsumer {

+

+    /**

+     * Donut receiver callback. This method is called when a donut is received

+     * on the listened topic.

+     * 

+     * @param donut

+     *            the received donut

+     */

+    void receiveDonut(Donut donut);

+

+    /**

+     * Event donut receiver callback. This method is called when an event is

+     * received on the listened topic.

+     * 

+     * @param event

+     *            the received event

+     */

+    void receiveEvent(Event event);

+

+    /**

+     * Clear the eaten donuts list. (Useful before tests)

+     */

+    void clearDonuts();

+

+    /**

+     * Get the first received donut and remove it from the eaten donut list.

+     * 

+     * @return the first received donut or null if no donut is available

+     */

+    Donut getDonut();

+

+    /**

+     * Get the whole list of eaten donuts.

+     * 

+     * @return the array containing all eaten donuts

+     */

+    Donut[] getAllDonuts();

+

+    /**

+     * Get the first donut if available or wait for an incoming donut. The

+     * returned donut is removed from the eaten donut list.

+     * 

+     * @return the first available donut.

+     */

+    Donut waitForDonut();

+

+    /**

+     * Return the size of the eaten donut list.

+     * 

+     * @return the size of the eaten donut list

+     */

+    int getNumberOfDonuts();

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumerImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumerImpl.java
new file mode 100644
index 0000000..fd7116e
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutConsumerImpl.java
@@ -0,0 +1,194 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * Implementation of a donut consumer.

+ *

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

+ * @see Homer Simpson

+ */

+public class DonutConsumerImpl implements DonutConsumer {

+

+

+    /**

+     * The time that is normally necessary to cause a blacklist from the event

+     * admin service.

+     */

+    public static final long BLACK_LIST_TIME = 5000L;

+    /**

+     * The name of the donut consumer.

+     */

+    private String m_name;

+    /**

+     * The list of eaten donuts.

+     */

+    private List m_donuts = new ArrayList();

+    /**

+     * Is this consumer a slow eater ?

+     */

+    private boolean m_isSlow;

+

+    /**

+     * Utility method that causes the current thread to sleep.

+     *

+     * @param millis the number of milliseconds to wait

+     */

+    public static void sleep(long millis) {

+        long past = System.currentTimeMillis();

+        long future = past + millis;

+        long now = past;

+        while (now < future) {

+            try {

+                Thread.sleep(future - now);

+            } catch (Exception e) {

+            }

+            now = System.currentTimeMillis();

+        }

+    }

+

+    /**

+     * Process incoming donuts. This method is called by the receiveDonut

+     * callback.

+     *

+     * @param donut the received donut

+     */

+    private void doReceiveDonut(Donut donut) {

+        synchronized (m_donuts) {

+            m_donuts.add(donut);

+            m_donuts.notify();

+        }

+    }

+

+    /**

+     * Donut receiver callback. This method is called when a donut is received

+     * on the listened topic.

+     *

+     * @param donut the received donut

+     */

+    public void receiveDonut(Donut donut) {

+        final Donut myDonut = donut;

+        if (m_isSlow) {

+            new Thread(new Runnable() {

+                public void run() {

+                    sleep(BLACK_LIST_TIME);

+                    doReceiveDonut(myDonut);

+                }

+            }, m_name + " eating " + donut).start();

+        } else {

+            doReceiveDonut(donut);

+        }

+    }

+

+    /**

+     * Event donut receiver callback. This method is called when an event is

+     * received on the listened topic.

+     *

+     * @param event the received event

+     */

+    public void receiveEvent(Event event) {

+        Object thing = event.getProperty("food");

+        if (Donut.class.isInstance(thing)) {

+            receiveDonut((Donut) thing);

+        } else {

+            // Nothing.

+        }

+    }

+

+    /**

+     * Clear the eaten donuts list. (Useful before tests)

+     */

+    public void clearDonuts() {

+        synchronized (m_donuts) {

+            m_donuts.clear();

+        }

+    }

+

+    /**

+     * Get the first received donut and remove it from the eaten donut list.

+     *

+     * @return the first received donut or null if no donut is available

+     */

+    public Donut getDonut() {

+        Donut donut = null;

+        synchronized (m_donuts) {

+            if (!m_donuts.isEmpty()) {

+                donut = (Donut) m_donuts.remove(0);

+            }

+        }

+        return donut;

+    }

+

+    /**

+     * Get the whole list of eaten donuts.

+     *

+     * @return the array containing all eaten donuts

+     */

+    public Donut[] getAllDonuts() {

+        Donut[] donuts = new Donut[0];

+        synchronized (m_donuts) {

+            donuts = (Donut[]) m_donuts.toArray(donuts);

+            m_donuts.clear();

+        }

+        return donuts;

+    }

+

+    /**

+     * Get the first donut if available or wait for an incoming donut. The

+     * returned donut is removed from the eaten donut list.

+     *

+     * @return the first available donut.

+     */

+    public Donut waitForDonut() {

+        Donut donut = null;

+        synchronized (m_donuts) {

+            while (donut == null) {

+                if (m_donuts.isEmpty()) {

+                    try {

+                        m_donuts.wait();

+                    } catch (InterruptedException e) {

+                        // Thanks Checkstyle to forbid empty catch statements

+                        // ;-(

+                    }

+                } else {

+                    donut = (Donut) m_donuts.remove(0);

+                }

+            }

+        }

+        return donut;

+    }

+

+    /**

+     * Return the size of the eaten donut list.

+     *

+     * @return the size of the eaten donut list

+     */

+    public int getNumberOfDonuts() {

+        int length;

+        synchronized (m_donuts) {

+            length = m_donuts.size();

+        }

+        return length;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutEventProviderImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutEventProviderImpl.java
new file mode 100644
index 0000000..2684706
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutEventProviderImpl.java
@@ -0,0 +1,74 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.apache.felix.ipojo.handlers.event.publisher.Publisher;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+import java.util.Random;

+

+/**

+ * Implementation of a donut vendor that send raw events instead of sending

+ * Donut objects.

+ *

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

+ */

+public class DonutEventProviderImpl implements DonutProvider {

+

+    /**

+     * The donut current serial number.

+     */

+    private long m_serial = 0L;

+    /**

+     * The name of the donut vendor.

+     */

+    private String m_name;

+    /**

+     * A random generator.

+     */

+    private Random m_random;

+    /**

+     * The event publisher of the donut vendor.

+     */

+    private Publisher m_publisher;

+

+    /**

+     * Construct a new donut provider. The initial serial number is randomly

+     * generated.

+     */

+    public DonutEventProviderImpl() {

+        m_random = new Random(System.currentTimeMillis());

+    }

+

+    /**

+     * Sell a donut with a random flavour.

+     *

+     * @return the sold donut

+     */

+    public Donut sellDonut() {

+        Dictionary rawEvent = new Hashtable();

+        String flavour = Donut.FLAVOURS[m_random.nextInt(Donut.FLAVOURS.length)];

+        Donut donut = new Donut(m_serial++, m_name, flavour);

+        rawEvent.put("food", donut);

+        rawEvent.put("flavour", flavour);

+        m_publisher.send(rawEvent);

+        return donut;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProvider.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProvider.java
new file mode 100644
index 0000000..748fd10
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProvider.java
@@ -0,0 +1,35 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+/**

+ * Specification of a donut vendor.

+ * 

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

+ * 

+ */

+public interface DonutProvider {

+

+    /**

+     * Sell a donut with a random flavour.

+     * 

+     * @return the sold donut

+     */

+    Donut sellDonut();

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProviderImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProviderImpl.java
new file mode 100644
index 0000000..085b9bc
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/DonutProviderImpl.java
@@ -0,0 +1,76 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.apache.felix.ipojo.handlers.event.publisher.Publisher;

+

+import java.util.Random;

+

+/**

+ * The standard implementation of a donut vendor.

+ * 

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

+ * 

+ */

+public class DonutProviderImpl implements DonutProvider {

+

+    

+

+    /**

+     * The donut current serial number.

+     */

+    private long m_serial = 0L;

+

+    /**

+     * The name of the donut vendor.

+     */

+    private String m_name;

+

+    /**

+     * A random generator.

+     */

+    private Random m_random;

+

+    /**

+     * The donut publisher of the vendor.

+     */

+    private Publisher m_publisher;

+

+    /**

+     * Construct a new donut provider. The initial serial number is randomly

+     * generated.

+     */

+    public DonutProviderImpl() {

+        m_random = new Random(System.currentTimeMillis());

+    }

+

+    /**

+     * Sell a donut with a random flavour.

+     * 

+     * @return the sold donut

+     */

+    public Donut sellDonut() {

+        Donut donut = new Donut(m_serial++, m_name, Donut.FLAVOURS[m_random

+                .nextInt(Donut.FLAVOURS.length)]);

+        m_publisher.sendData(donut);

+        System.err.println("[" + this.getClass().getSimpleName() + ":"

+                    + m_name + "] Selling donut " + donut);

+        return donut;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventConsumerImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventConsumerImpl.java
new file mode 100644
index 0000000..3fc27ab
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventConsumerImpl.java
@@ -0,0 +1,199 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+import org.osgi.service.event.EventHandler;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * Implementation of a donut consumer.

+ *

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

+ * @see Homer Simpson

+ */

+public class EventConsumerImpl implements DonutConsumer, EventHandler {

+

+    /**

+     * The name of the donut consumer.

+     */

+    private String m_name;

+    /**

+     * The list of eaten donuts.

+     */

+    private List m_donuts = new ArrayList();

+    /**

+     * Is this consumer a slow eater ?

+     */

+    private boolean m_isSlow;

+

+    /**

+     * Utility method that causes the current thread to sleep.

+     *

+     * @param millis the number of milliseconds to wait

+     */

+    public static void sleep(long millis) {

+        long past = System.currentTimeMillis();

+        long future = past + millis;

+        long now = past;

+        while (now < future) {

+            try {

+                Thread.sleep(future - now);

+            } catch (Exception e) {

+            }

+            now = System.currentTimeMillis();

+        }

+    }

+

+    /**

+     * Process incoming donuts. This method is called by the receiveDonut

+     * callback.

+     *

+     * @param donut the received donut

+     */

+    private void doReceiveDonut(Donut donut) {

+        synchronized (m_donuts) {

+            m_donuts.add(donut);

+            m_donuts.notify();

+        }

+    }

+

+    /**

+     * Donut receiver callback. This method is called when a donut is received

+     * on the listened topic.

+     *

+     * @param donut the received donut

+     */

+    public void receiveDonut(Donut donut) {

+        final Donut myDonut = donut;

+        if (m_isSlow) {

+            new Thread(new Runnable() {

+                public void run() {

+                    sleep(DonutConsumerImpl.BLACK_LIST_TIME);

+                    doReceiveDonut(myDonut);

+                }

+            }, m_name + " eating " + donut).start();

+        } else {

+            doReceiveDonut(donut);

+        }

+    }

+

+    /**

+     * Event donut receiver callback. This method is called when an event is

+     * received on the listened topic.

+     *

+     * @param event the received event

+     */

+    public void receiveEvent(Event event) {

+        Object thing = event.getProperty("food");

+        if (Donut.class.isInstance(thing)) {

+            receiveDonut((Donut) thing);

+        } else {

+            // Nothing to do.

+        }

+    }

+

+    /**

+     * Event receiver callback. This method is called by the event admin service

+     * when a event is received.

+     *

+     * @param event the received event

+     */

+    public void handleEvent(Event event) {

+        receiveEvent(event);

+    }

+

+    /**

+     * Clear the eaten donuts list. (Useful before tests)

+     */

+    public void clearDonuts() {

+        synchronized (m_donuts) {

+            m_donuts.clear();

+        }

+    }

+

+    /**

+     * Get the first received donut and remove it from the eaten donut list.

+     *

+     * @return the first received donut or null if no donut is available

+     */

+    public Donut getDonut() {

+        Donut donut = null;

+        synchronized (m_donuts) {

+            if (!m_donuts.isEmpty()) {

+                donut = (Donut) m_donuts.remove(0);

+            }

+        }

+        return donut;

+    }

+

+    /**

+     * Get the whole list of eaten donuts.

+     *

+     * @return the array containing all eaten donuts

+     */

+    public Donut[] getAllDonuts() {

+        Donut[] donuts = new Donut[0];

+        synchronized (m_donuts) {

+            donuts = (Donut[]) m_donuts.toArray(donuts);

+            m_donuts.clear();

+        }

+        return donuts;

+    }

+

+    /**

+     * Get the first donut if available or wait for an incoming donut. The

+     * returned donut is removed from the eaten donut list.

+     *

+     * @return the first available donut.

+     */

+    public Donut waitForDonut() {

+        Donut donut = null;

+        synchronized (m_donuts) {

+            while (donut == null) {

+                if (m_donuts.isEmpty()) {

+                    try {

+                        m_donuts.wait();

+                    } catch (InterruptedException e) {

+                        // Thanks Checkstyle to forbid empty catch statements

+                        // ;-(

+                    }

+                } else {

+                    donut = (Donut) m_donuts.remove(0);

+                }

+            }

+        }

+        return donut;

+    }

+

+    /**

+     * Return the size of the eaten donut list.

+     *

+     * @return the size of the eaten donut list

+     */

+    public int getNumberOfDonuts() {

+        int length;

+        synchronized (m_donuts) {

+            length = m_donuts.size();

+        }

+        return length;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTracker.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTracker.java
new file mode 100644
index 0000000..df45809
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTracker.java
@@ -0,0 +1,63 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+

+/**

+ * Specification of an event tracker.

+ * 

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

+ */

+public interface EventTracker {

+

+    /**

+     * Clear the received events list. (Useful before tests)

+     */

+    void clearEvents();

+

+    /**

+     * Get the first received event and remove it from the events list.

+     * 

+     * @return the first received event or null if no event is available

+     */

+    Event getEvent();

+

+    /**

+     * Get the whole list of received events.

+     * 

+     * @return the array containing all received events

+     */

+    Event[] getAllEvents();

+

+    /**

+     * Get the first event if available or wait for an incoming event. The

+     * returned event is removed from the eaten event list.

+     * 

+     * @return the first available event.

+     */

+    Event waitForEvent();

+

+    /**

+     * Return the size of the events list.

+     * 

+     * @return the size of the events list

+     */

+    int getNumberOfEvents();

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTrackerImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTrackerImpl.java
new file mode 100644
index 0000000..e79d5ff
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/EventTrackerImpl.java
@@ -0,0 +1,152 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+import org.osgi.service.event.EventHandler;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * Implementation of an event tracker.

+ *

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

+ */

+public class EventTrackerImpl implements EventTracker, EventHandler {

+

+    /**

+     * The name of the event tracker.

+     */

+    private String m_name;

+    /**

+     * The list of received events

+     */

+    private List m_events = new ArrayList();

+

+    /**

+     * Return the string representation of a given event.

+     *

+     * @return the string representation of a given event

+     */

+    public static String eventToString(Event e) {

+        StringBuilder buf = new StringBuilder();

+        buf.append("[" + e.getTopic() + "] {");

+

+        String[] properties = e.getPropertyNames();

+        int n = properties.length - 1;

+        for (int i = 0; i <= n; i++) {

+            String name = properties[i];

+            buf.append(name + "=" + e.getProperty(name));

+            if (i != n)

+                buf.append(", ");

+        }

+        buf.append("}");

+        return buf.toString();

+    }

+

+    /**

+     * Event receiver callback. This method is called by the event admin service

+     * when a event is received.

+     *

+     * @param event the received event

+     */

+    public void handleEvent(Event event) {

+        synchronized (m_events) {

+            m_events.add(event);

+            m_events.notify();

+        }

+    }

+

+    /**

+     * Clear the received events list. (Useful before tests)

+     */

+    public void clearEvents() {

+        synchronized (m_events) {

+            m_events.clear();

+        }

+    }

+

+    /**

+     * Get the first received event and remove it from the events list.

+     *

+     * @return the first received event or null if no event is available

+     */

+    public Event getEvent() {

+        Event event = null;

+        synchronized (m_events) {

+            if (!m_events.isEmpty()) {

+                event = (Event) m_events.remove(0);

+            }

+        }

+        return event;

+    }

+

+    /**

+     * Get the whole list of received events.

+     *

+     * @return the array containing all received events

+     */

+    public Event[] getAllEvents() {

+        Event[] events = new Event[0];

+        synchronized (m_events) {

+            events = (Event[]) m_events.toArray(events);

+            m_events.clear();

+        }

+        return events;

+    }

+

+    /**

+     * Get the first event if available or wait for an incoming event. The

+     * returned event is removed from the eaten event list.

+     *

+     * @return the first available event.

+     */

+    public Event waitForEvent() {

+        Event event = null;

+        synchronized (m_events) {

+            while (event == null) {

+                if (m_events.isEmpty()) {

+                    try {

+                        m_events.wait();

+                    } catch (InterruptedException e) {

+                        // Thanks Checkstyle to forbid empty catch statements

+                        // ;-(

+                    }

+                } else {

+                    event = (Event) m_events.remove(0);

+                }

+            }

+        }

+        return event;

+    }

+

+    /**

+     * Return the size of the events list.

+     *

+     * @return the size of the events list

+     */

+    public int getNumberOfEvents() {

+        int length;

+        synchronized (m_events) {

+            length = m_events.size();

+        }

+        return length;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/SyncEventProviderImpl.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/SyncEventProviderImpl.java
new file mode 100644
index 0000000..332ccc7
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/java/org/apache/felix/ipojo/handler/eventadmin/test/donut/SyncEventProviderImpl.java
@@ -0,0 +1,74 @@
+/* 

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test.donut;

+

+import org.osgi.service.event.Event;

+import org.osgi.service.event.EventAdmin;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+import java.util.Random;

+

+/**

+ * Implementation of an event vendor that directly uses the Event Admin service

+ * to send (synchronously) raw events.

+ *

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

+ */

+public class SyncEventProviderImpl implements DonutProvider {

+

+    /**

+     * The donut current serial number.

+     */

+    private long m_serial = 0L;

+    /**

+     * The name of the donut vendor.

+     */

+    private String m_name;

+    /**

+     * A random generator.

+     */

+    private Random m_random;

+    /**

+     * The Event Admin service reference.

+     */

+    private EventAdmin m_ea;

+

+    /**

+     * Construct a new donut provider. The initial serial number is randomly

+     * generated.

+     */

+    public SyncEventProviderImpl() {

+        m_random = new Random(System.currentTimeMillis());

+    }

+

+    /**

+     * Sell a donut with a random flavour.

+     *

+     * @return the sold donut

+     */

+    public Donut sellDonut() {

+        Dictionary rawEvent = new Hashtable();

+        Donut donut = new Donut(m_serial++, m_name, Donut.FLAVOURS[m_random

+                .nextInt(Donut.FLAVOURS.length)]);

+        rawEvent.put("food", donut);

+        m_ea.sendEvent(new Event("food/donuts", rawEvent));

+        return donut;

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/resources/metadata.xml b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/resources/metadata.xml
new file mode 100644
index 0000000..00b59c9
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/main/resources/metadata.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
+	xmlns="org.apache.felix.ipojo"
+	xmlns:ev="org.apache.felix.ipojo.handlers.event">
+
+	<!-- The (asynchronous) donut provider -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProviderImpl"
+		name="donut-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Donut publisher -->
+		<ev:publisher name="donut-publisher" field="m_publisher"
+			topics="food/donuts" data-key="food" synchronous="false"/>
+	</component>
+
+		<!-- The (asynchronous) donut provider using publishes -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProviderImpl"
+		name="donut-provider-publishes">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Donut publisher -->
+		<ev:publishes name="donut-publisher" field="m_publisher"
+			topics="food/donuts" dataKey="food" synchronous="false"/>
+	</component>
+
+	<!-- The synchronous donut provider -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProviderImpl"
+		name="synchronous-donut-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Donut publisher -->
+		<ev:publisher name="donut-publisher" field="m_publisher"
+			topics="food/donuts" data-key="food" synchronous="true"/>
+	</component>
+
+		<!-- The synchronous donut provider using dataKey -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProviderImpl"
+		name="synchronous-donut-provider-2">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Donut publisher -->
+		<ev:publisher name="donut-publisher" field="m_publisher"
+			topics="food/donuts" dataKey="food" synchronous="true"/>
+	</component>
+
+	<!-- The (asynchronous) donut event provider -->
+	<component
+		classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutEventProviderImpl"
+		name="donut-event-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Raw events publisher -->
+		<ev:publisher name="event-publisher" field="m_publisher"
+			topics="food/donuts" synchronous="false"/>
+	</component>
+
+	<!-- The synchronous donut event provider -->
+	<component
+		classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutEventProviderImpl"
+		name="synchronous-donut-event-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Raw events publisher -->
+		<ev:publisher name="event-publisher" field="m_publisher"
+			topics="food/donuts" synchronous="true"/>
+	</component>
+
+	<!-- The (asynchronous) event provider -->
+	<component
+		classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.AsyncEventProviderImpl"
+		name="event-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Direcly interacts with the Event Admin service -->
+		<requires field="m_ea"/>
+	</component>
+
+	<!-- The synchronous event provider -->
+	<component
+		classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.SyncEventProviderImpl"
+		name="synchronous-event-provider">
+		<!-- Expose the donut provider service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider">
+			<property name="name" field="m_name" value="Unknown donut vendor"/>
+		</provides>
+		<!-- Direcly interacts with the Event Admin service -->
+		<requires field="m_ea"/>
+	</component>
+
+	<!-- The donut consumer -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumerImpl"
+		name="donut-consumer">
+		<!-- Expose the donut consumer service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer">
+			<property name="name" field="m_name" value="Unknown donut consumer"/>
+			<property name="slow" field="m_isSlow" value="false"/>
+		</provides>
+		<!-- Donut events subscriber -->
+		<ev:subscriber name="donut-subscriber" callback="receiveDonut"
+			topics="food/donuts" data-key="food"
+			data-type="org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut"/>
+	</component>
+
+		<!-- The donut consumer using dataKey and dataType -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumerImpl"
+		name="donut-consumer-2">
+		<!-- Expose the donut consumer service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer">
+			<property name="name" field="m_name" value="Unknown donut consumer"/>
+			<property name="slow" field="m_isSlow" value="false"/>
+		</provides>
+		<!-- Donut events subscriber -->
+		<ev:subscriber name="donut-subscriber" callback="receiveDonut"
+			topics="food/donuts" dataKey="food"
+			dataType="org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut"/>
+	</component>
+
+
+	<!-- The donut event consumer -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumerImpl"
+		name="donut-event-consumer">
+		<!-- Expose the donut consumer service -->
+		<provides specifications="org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer">
+			<property name="name" field="m_name" value="Unknown donut consumer"/>
+			<property name="slow" field="m_isSlow" value="false"/>
+		</provides>
+		<!-- Raw events subscriber -->
+		<ev:subscriber name="donut-event-subscriber" callback="receiveEvent"
+			topics="food/donuts"/>
+	</component>
+
+	<!-- The event consumer -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.EventConsumerImpl"
+		name="event-consumer">
+		<!-- Expose the donut consumer service -->
+		<provides
+			specifications="{org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer,org.osgi.service.event.EventHandler}">
+			<property name="name" field="m_name" value="Unknown event consumer"/>
+			<property name="slow" field="m_isSlow" value="false"/>
+			<property name="event.topics" type="String" value="food/donuts"/>
+		</provides>
+	</component>
+
+	<!-- The event tracker -->
+	<component classname="org.apache.felix.ipojo.handler.eventadmin.test.donut.EventTrackerImpl"
+		name="event-tracker">
+		<!-- Expose the donut consumer service -->
+		<provides
+			specifications="{org.apache.felix.ipojo.handler.eventadmin.test.donut.EventTracker,org.osgi.service.event.EventHandler}">
+			<property name="name" field="m_name" value="Unknown event tracker"/>
+			<property name="event.topics" type="String" value="food/donuts"/>
+		</provides>
+	</component>
+
+
+	<!-- Example instances -->
+	<instance component="donut-provider" name="zeifhgbzre">
+		<property name="name" value="Zeifhgbzre donuts"/>
+	</instance>
+	<instance component="donut-consumer" name="zeifhgbzre simpson">
+		<property name="name" value="Zeifhgbzre simpson"/>
+		<property name="slow" value="false"/>
+	</instance>
+
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/Common.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/Common.java
new file mode 100644
index 0000000..4275b5f
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/Common.java
@@ -0,0 +1,203 @@
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.CoreOptions;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.options.CompositeOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.options.libraries.JUnitBundlesOption;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.ow2.chameleon.testing.helpers.IPOJOHelper;
+import org.ow2.chameleon.testing.helpers.OSGiHelper;
+import org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static junit.framework.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.*;
+
+/**
+ * Bootstrap the test from this project
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class Common {
+
+    @Inject
+    BundleContext bc;
+
+    OSGiHelper osgiHelper;
+    IPOJOHelper ipojoHelper;
+
+    Bundle testedBundle;
+
+    @Configuration
+    public Option[] config() throws IOException {
+        Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+        root.setLevel(Level.DEBUG);
+
+        return options(
+                cleanCaches(),
+                ipojoBundles(),
+                junitBundles(),
+                eventadmin(),
+                testedBundle(),
+                systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("WARN")
+        );
+    }
+
+    public CompositeOption eventadmin() {
+        return new DefaultCompositeOption(
+                mavenBundle("org.apache.felix", "org.apache.felix.eventadmin", "1.3.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.ipojo.handler.eventadmin").versionAsInProject());
+    }
+
+    public static Option junitAndMockitoBundles() {
+        return new DefaultCompositeOption(
+                // Repository required to load harmcrest (OSGi-fied version).
+                repository("http://repository.springsource.com/maven/bundles/external").id(
+                        "com.springsource.repository.bundles.external"),
+
+                // Hamcrest with a version matching the range expected by Mockito
+                mavenBundle("org.hamcrest", "com.springsource.org.hamcrest.core", "1.1.0"),
+
+                // Mockito core does not includes Hamcrest
+                mavenBundle("org.mockito", "mockito-core", "1.9.5"),
+
+                // Objenesis with a version matching the range expected by Mockito
+                wrappedBundle(mavenBundle("org.objenesis", "objenesis", "1.2"))
+                        .exports("*;version=1.2"),
+
+                // The default JUnit bundle also exports Hamcrest, but with an (incorrect) version of
+                // 4.9 which does not match the Mockito import. When deployed after the hamcrest bundles, it gets
+                // resolved correctly.
+                CoreOptions.junitBundles(),
+
+                /*
+                 * Felix has implicit boot delegation enabled by default. It conflicts with Mockito:
+                 * java.lang.LinkageError: loader constraint violation in interface itable initialization:
+                 * when resolving method "org.osgi.service.useradmin.User$$EnhancerByMockitoWithCGLIB$$dd2f81dc
+                 * .newInstance(Lorg/mockito/cglib/proxy/Callback;)Ljava/lang/Object;" the class loader
+                 * (instance of org/mockito/internal/creation/jmock/SearchingClassLoader) of the current class,
+                 * org/osgi/service/useradmin/User$$EnhancerByMockitoWithCGLIB$$dd2f81dc, and the class loader
+                 * (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for interface
+                 * org/mockito/cglib/proxy/Factory have different Class objects for the type org/mockito/cglib/
+                 * proxy/Callback used in the signature
+                 *
+                 * So we disable the bootdelegation. this property has no effect on the other OSGi implementation.
+                 */
+                frameworkProperty("felix.bootdelegation.implicit").value("false")
+        );
+    }
+
+    @Before
+    public void commonSetUp() {
+        osgiHelper = new OSGiHelper(bc);
+        ipojoHelper = new IPOJOHelper(bc);
+
+        testedBundle = osgiHelper.getBundle("test.bundle");
+
+        // Dump OSGi Framework information
+        String vendor = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_VENDOR);
+        if (vendor == null) {
+            vendor = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_SYMBOLICNAME);
+        }
+        String version = (String) osgiHelper.getBundle(0).getHeaders().get(Constants.BUNDLE_VERSION);
+        System.out.println("OSGi Framework : " + vendor + " - " + version);
+    }
+
+    @After
+    public void commonTearDown() {
+        ipojoHelper.dispose();
+        osgiHelper.dispose();
+    }
+
+    public static CompositeOption ipojoBundles() {
+        return new DefaultCompositeOption(
+                mavenBundle("org.apache.felix", "org.apache.felix.ipojo").versionAsInProject(),
+                mavenBundle("org.ow2.chameleon.testing", "osgi-helpers").versionAsInProject()
+        );
+    }
+
+    public Option testedBundle() throws MalformedURLException {
+        File out = new File("target/tested/bundle.jar");
+
+        TinyBundle tested = TinyBundles.bundle();
+
+        // We look inside target/classes to find the class and resources
+        File classes = new File("target/classes");
+        Collection<File> files = FileUtils.listFilesAndDirs(classes, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
+        List<File> services = new ArrayList<File>();
+        for (File file : files) {
+            if (file.isDirectory()) {
+                // By convention we export of .services and .service package
+                if (file.getName().endsWith("services")  || file.getName().endsWith("service")) {
+                    services.add(file);
+                }
+            } else {
+                // We need to compute the path
+                String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1);
+                tested.add(path, file.toURI().toURL());
+                System.out.println(file.getName() + " added to " + path);
+            }
+        }
+
+        String export = "org.apache.felix.ipojo.handler.eventadmin.test.donut";
+        for (File file : services) {
+            if (export.length() > 0) { export += ", "; }
+            String path = file.getAbsolutePath().substring(classes.getAbsolutePath().length() +1);
+            String packageName = path.replace('/', '.');
+            export += packageName;
+        }
+
+        System.out.println("Exported packages : " + export);
+
+        InputStream inputStream = tested
+                .set(Constants.BUNDLE_SYMBOLICNAME, "test.bundle")
+                .set(Constants.IMPORT_PACKAGE, "*")
+                .set(Constants.EXPORT_PACKAGE, export)
+                .build(IPOJOStrategy.withiPOJO(new File("src/main/resources")));
+
+        try {
+            FileUtils.copyInputStreamToFile(inputStream, out);
+            return bundle(out.toURI().toURL().toExternalForm());
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Cannot compute the url of the manipulated bundle");
+        } catch (IOException e) {
+            throw new RuntimeException("Cannot write of the manipulated bundle");
+        }
+    }
+
+    public void assertContains(String s, String[] arrays, String object) {
+        for (String suspect : arrays) {
+            if (object.equals(suspect)) {
+                return;
+            }
+        }
+        fail("Assertion failed : " + s);
+    }
+
+
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/EahTestUtils.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/EahTestUtils.java
new file mode 100644
index 0000000..47786db
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/EahTestUtils.java
@@ -0,0 +1,225 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.felix.ipojo.handler.eventadmin.test;

+

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

+import org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut;

+import org.osgi.framework.BundleContext;

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

+

+/**

+ * Useful variables used for the tests of the Event Admin Handler.

+ *

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

+ */

+public class EahTestUtils {

+

+    /**

+     * Enable debug messages ?

+     */

+    public static final boolean TRACE = false;

+    /**

+     * The number of tests to execute.

+     */

+    public static final int NUMBER_OF_TESTS = 50;

+    /**

+     * The time that is normally necessary to cause a blacklist from the event

+     * admin service.

+     */

+    public static final long BLACK_LIST_TIME = 5000L;

+    /**

+     * The long amount of time.

+     */

+    public static final long A_LONG_TIME = 1000L;

+    /**

+     * The bundle context.

+     */

+    private BundleContext m_context;

+    /**

+     * The iPOJO Helper.

+     */

+    private IPOJOHelper m_ipojoHelper;

+

+    /**

+     * Construct a new Event Admin Handler Tests utility instance.

+     */

+    public EahTestUtils(BundleContext context, IPOJOHelper ipojoHelper) {

+        m_ipojoHelper = ipojoHelper;

+        m_context = context;

+    }

+

+    /**

+     * Utility method that causes the current thread to sleep.

+     *

+     * @param millis the number of milliseconds to wait

+     */

+    public static void sleep(long millis) {

+        long past = System.currentTimeMillis();

+        long future = past + millis;

+        long now = past;

+        if (TRACE) {

+            System.err.println("Sleeping for " + millis + "ms");

+        }

+        while (now < future) {

+            try {

+                Thread.sleep(future - now);

+            } catch (Exception e) {

+            }

+            now = System.currentTimeMillis();

+        }

+    }

+

+    /**

+     * Return the index of the given donut flavour in the flavour array.

+     *

+     * @return the index of the given flavour or -1 if not found

+     */

+    public static int flavourIndex(String flavour) {

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

+            if (Donut.FLAVOURS[i].equals(flavour))

+                return i;

+        }

+        return -1;

+    }

+

+    /**

+     * Return the (asynchronous) donut provider factory.

+     *

+     * @return the (asynchronous) donut provider factory

+     */

+    public Factory getDonutProviderFactory() {

+        return m_ipojoHelper.getFactory("donut-provider");

+    }

+

+    /**

+     * Return the (asynchronous) donut provider using publishes factory.

+     *

+     * @return the (asynchronous) donut provider using publishes factory

+     */

+    public Factory getDonutProviderUsingPublishesFactory() {

+        return m_ipojoHelper.getFactory("donut-provider-publishes");

+    }

+

+    /**

+     * Return the synchronous donut provider factory.

+     *

+     * @return the synchronous donut provider factory

+     */

+    public Factory getSynchronousDonutProviderFactory() {

+        return m_ipojoHelper.getFactory(

+                "synchronous-donut-provider");

+    }

+

+    /**

+     * Return the synchronous donut provider factory using

+     * dataKey

+     *

+     * @return the synchronous donut provider factory

+     */

+    public Factory getSynchronousDonutProvider2Factory() {

+        return m_ipojoHelper.getFactory(

+                "synchronous-donut-provider-2");

+    }

+

+    /**

+     * Return the (asynchronous) donut event provider factory.

+     *

+     * @return the (asynchronous) donut event provider factory

+     */

+    public Factory getDonutEventProviderFactory() {

+        return m_ipojoHelper.getFactory(

+                "donut-event-provider");

+    }

+

+    /**

+     * Return the synchronous donut event provider factory.

+     *

+     * @return the synchronous donut event provider factory

+     */

+    public Factory getSynchronousDonutEventProviderFactory() {

+        return m_ipojoHelper.getFactory(

+                "synchronous-donut-event-provider");

+    }

+

+    /**

+     * Return the event provider factory.

+     *

+     * @return the event provider factory

+     */

+    public Factory getEventProviderFactory() {

+        return m_ipojoHelper.getFactory("event-provider");

+    }

+

+    /**

+     * Return the synchronous event provider factory.

+     *

+     * @return the synchronous event provider factory

+     */

+    public Factory getSynchronousEventProviderFactory() {

+        return m_ipojoHelper.getFactory(

+                "synchronous-event-provider");

+    }

+

+    /**

+     * Return the donut consumer factory.

+     *

+     * @return the donut consumer factory

+     */

+    public Factory getDonutConsumerFactory() {

+        return m_ipojoHelper.getFactory("donut-consumer");

+    }

+

+    /**

+     * Return the donut consumer factory using dataKey

+     * and dataType.

+     *

+     * @return the donut consumer factory

+     */

+    public Factory getDonutConsumer2Factory() {

+        return m_ipojoHelper.getFactory("donut-consumer-2");

+    }

+

+    /**

+     * Return the donut event consumer factory.

+     *

+     * @return the donut event consumer factory

+     */

+    public Factory getDonutEventConsumerFactory() {

+        return m_ipojoHelper.getFactory(

+                "donut-event-consumer");

+    }

+

+    /**

+     * Return the event consumer factory.

+     *

+     * @return the event consumer factory

+     */

+    public Factory getEventConsumerFactory() {

+        return m_ipojoHelper.getFactory("event-consumer");

+    }

+

+    /**

+     * Return the event tracker.

+     *

+     * @return the event consumer factory

+     */

+    public Factory getEventTrackerFactory() {

+        return m_ipojoHelper.getFactory("event-tracker");

+    }

+}

diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/SimpleTest.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/SimpleTest.java
new file mode 100644
index 0000000..3323701
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/SimpleTest.java
@@ -0,0 +1,22 @@
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import javax.inject.Inject;
+
+
+public class SimpleTest extends Common {
+
+    @Inject
+    BundleContext bc;
+
+    @Test
+    public void testSomethingStupid() {
+        System.out.println("This is fucking weird");
+        for (Bundle bundle : bc.getBundles()) {
+            System.out.println(bundle.getSymbolicName() + " " + bundle.getState());
+        }
+    }
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestBadConfigurations.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestBadConfigurations.java
new file mode 100644
index 0000000..6da354e
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestBadConfigurations.java
@@ -0,0 +1,958 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import org.apache.felix.ipojo.*;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test the good behaviour of the EventAdminHandler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestBadConfigurations extends Common {
+
+    /**
+     * The namespace of the Event admin handler.
+     */
+    private static final String NAMESPACE = "org.apache.felix.ipojo.handlers.event";
+    /**
+     * The utility class instance.
+     */
+    public EahTestUtils m_utils;
+    /**
+     * The available components.
+     */
+    private Element[] m_components;
+    /**
+     * The description of a component that uses an event publisher.
+     */
+    private Element m_provider;
+    /**
+     * The event publisher description.
+     */
+    private Element m_publisher;
+    /**
+     * The name attribute of the event publisher.
+     */
+    private Attribute m_publisherName;
+    /**
+     * The field attribute of the event publisher.
+     */
+    private Attribute m_publisherField;
+    /**
+     * The topics attribute of the event publisher.
+     */
+    private Attribute m_publisherTopics;
+    /**
+     * The data-key attribute of the event publisher.
+     */
+    private Attribute m_publisherDataKey;
+    /**
+     * The synchronous attribute of the event publisher.
+     */
+    private Attribute m_publisherSynchronous;
+    /**
+     * The description of a component that uses an event subscriber.
+     */
+    private Element m_consumer;
+    /**
+     * The event subscriber description.
+     */
+    private Element m_subscriber;
+    /**
+     * The name attribute of the event subscriber.
+     */
+    private Attribute m_subscriberName;
+    /**
+     * The callback attribute of the event subscriber.
+     */
+    private Attribute m_subscriberCallback;
+    /**
+     * The topics attribute of the event subscriber.
+     */
+    private Attribute m_subscriberTopics;
+    /**
+     * The data-key attribute of the event subscriber.
+     */
+    private Attribute m_subscriberDataKey;
+    /**
+     * The data-type attribute of the event subscriber.
+     */
+    private Attribute m_subscriberDataType;
+
+    private Element getManipulationForComponent(String compName) {
+        for (int i = 0; i < m_components.length; i++) {
+            if (m_components[i].containsAttribute("name")
+                    && m_components[i].getAttribute("name").equals(compName)) {
+                return m_components[i].getElements("manipulation")[0];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Initialization before test cases.
+     * <p/>
+     * Create all the instances
+     */
+    @Before
+    public void setUp() {
+        m_utils = new EahTestUtils(bc, ipojoHelper);
+        /**
+         * Get the list of available components.
+         */
+        try {
+            String header = (String) testedBundle.getHeaders().get(
+                    "iPOJO-Components");
+            m_components = ManifestMetadataParser.parseHeaderMetadata(header)
+                    .getElements("component");
+        } catch (ParseException e) {
+            fail("Parse Exception when parsing iPOJO-Component");
+        }
+
+        /**
+         * Initialize the standard publishing component (based on the
+         * asynchronous donut provider).
+         */
+        m_provider = new Element("component", "");
+        m_provider.addAttribute(new Attribute("className",
+                "org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProviderImpl"));
+        m_provider.addAttribute(new Attribute("name",
+                "standard donut provider for bad tests"));
+
+        // The provided service of the publisher
+        Element providesDonutProvider = new Element("provides", "");
+        providesDonutProvider.addAttribute(new Attribute("interface",
+                "org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider"));
+        Element providesDonutProviderProperty = new Element("property", "");
+        providesDonutProviderProperty
+                .addAttribute(new Attribute("name", "name"));
+        providesDonutProviderProperty.addAttribute(new Attribute("field",
+                "m_name"));
+        providesDonutProviderProperty.addAttribute(new Attribute("value",
+                "Unknown donut vendor"));
+        providesDonutProvider.addElement(providesDonutProviderProperty);
+        m_provider.addElement(providesDonutProvider);
+
+        // The event publisher, corresponding to the following description :
+        // <ev:publisher name="donut-publisher" field="m_publisher"
+        // topics="food/donuts" data-key="food" synchronous="false"/>
+        m_publisher = new Element("publisher", NAMESPACE);
+        m_publisherName = new Attribute("name", "donut-publisher");
+        m_publisherField = new Attribute("field", "m_publisher");
+        m_publisherTopics = new Attribute("topics", "food/donuts");
+        m_publisherDataKey = new Attribute("data-key", "food");
+        m_publisherSynchronous = new Attribute("synchronous", "false");
+        m_publisher.addAttribute(m_publisherName);
+        m_publisher.addAttribute(m_publisherField);
+        m_publisher.addAttribute(m_publisherTopics);
+        m_publisher.addAttribute(m_publisherDataKey);
+        m_publisher.addAttribute(m_publisherSynchronous);
+        m_provider.addElement(m_publisher);
+
+        m_provider.addElement(getManipulationForComponent("donut-provider"));
+
+        /**
+         * Initialize the standard subscribing component (based on the donut
+         * consumer).
+         */
+        m_consumer = new Element("component", "");
+        m_consumer.addAttribute(new Attribute("className",
+                "org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumerImpl"));
+        m_consumer.addAttribute(new Attribute("name",
+                "standard donut consumer for bad tests"));
+
+        // The provided service of the publisher
+        Element providesDonutConsumer = new Element("provides", "");
+        providesDonutConsumer.addAttribute(new Attribute("interface",
+                "org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer"));
+        Element providesDonutConsumerNameProperty = new Element("property", "");
+        providesDonutConsumerNameProperty.addAttribute(new Attribute("name",
+                "name"));
+        providesDonutConsumerNameProperty.addAttribute(new Attribute("field",
+                "m_name"));
+        providesDonutConsumerNameProperty.addAttribute(new Attribute("value",
+                "Unknown donut consumer"));
+        providesDonutConsumer.addElement(providesDonutConsumerNameProperty);
+        Element providesDonutConsumerSlowProperty = new Element("property", "");
+        providesDonutConsumerSlowProperty.addAttribute(new Attribute("name",
+                "slow"));
+        providesDonutConsumerSlowProperty.addAttribute(new Attribute("field",
+                "m_isSlow"));
+        providesDonutConsumerSlowProperty.addAttribute(new Attribute("value",
+                "false"));
+        providesDonutConsumer.addElement(providesDonutConsumerSlowProperty);
+        m_consumer.addElement(providesDonutConsumer);
+
+        // The event publisher, corresponding to the following description :
+        // <ev:subscriber name="donut-subscriber" callback="receiveDonut"
+        // topics="food/donuts" data-key="food"
+        // data-type="org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut"/>
+        m_subscriber = new Element("subscriber", NAMESPACE);
+        m_subscriberName = new Attribute("name", "donut-subscriber");
+        m_subscriberCallback = new Attribute("callback", "receiveDonut");
+        m_subscriberTopics = new Attribute("topics", "food/donuts");
+        m_subscriberDataKey = new Attribute("data-key", "food");
+        m_subscriberDataType = new Attribute("data-type",
+                "org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut");
+        m_subscriber.addAttribute(m_subscriberName);
+        m_subscriber.addAttribute(m_subscriberCallback);
+        m_subscriber.addAttribute(m_subscriberTopics);
+        m_subscriber.addAttribute(m_subscriberDataKey);
+        m_subscriber.addAttribute(m_subscriberDataType);
+        m_consumer.addElement(m_subscriber);
+
+        m_consumer.addElement(getManipulationForComponent("donut-consumer"));
+    }
+
+    /**
+     * Test the base configuration is correct to be sure the bad tests will fail
+     * because of they are really bad, and not because of an other application
+     * error.
+     * <p/>
+     * This test simply create a provider and a consumer instance, send one
+     * event and check it is received.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testGoodConfig()
+            throws ConfigurationException, UnacceptableConfiguration,
+            MissingHandlerException {
+        /**
+         * Create the provider and the consumer instances.
+         */
+        Dictionary properties = new Hashtable();
+
+        // Provider
+        ComponentFactory providerFactory = new ComponentFactory(bc,
+                m_provider);
+        providerFactory.start();
+        properties.put("instance.name", "Emperor of donuts");
+        ComponentInstance providerInstance = providerFactory
+                .createComponentInstance(properties);
+        ServiceReference providerService = ipojoHelper
+                .getServiceReferenceByName(DonutProvider.class
+                        .getName(), providerInstance.getInstanceName());
+        DonutProvider provider = (DonutProvider) bc
+                .getService(providerService);
+
+        // The consumer
+        properties = new Hashtable();
+        ComponentFactory consumerFactory = new ComponentFactory(bc,
+                m_consumer);
+        consumerFactory.start();
+        properties.put("instance.name", "Homer Simpson");
+        properties.put("slow", "false");
+        ComponentInstance consumerInstance = consumerFactory
+                .createComponentInstance(properties);
+        ServiceReference consumerService = ipojoHelper
+                .getServiceReferenceByName(DonutConsumer.class
+                        .getName(), consumerInstance.getInstanceName());
+        DonutConsumer consumer = (DonutConsumer) bc
+                .getService(consumerService);
+
+        /**
+         * Test the normal behaviour of the instances.
+         */
+        consumer.clearDonuts();
+        Donut sentDonut = provider.sellDonut();
+        Donut receivedDonut = consumer.waitForDonut();
+        assertEquals("The received donut must be the same as the sent one.",
+                sentDonut, receivedDonut);
+
+        /**
+         * Destroy component's instances.
+         */
+        bc.ungetService(providerService);
+        providerInstance.dispose();
+        bc.ungetService(consumerService);
+        consumerInstance.dispose();
+        providerFactory.stop();
+        consumerFactory.stop();
+    }
+
+    /**
+     * Try to create a publisher with no name.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithoutName()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher
+        m_publisher.removeAttribute(m_publisherName);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when no name is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.addAttribute(m_publisherName);
+        }
+    }
+
+    /**
+     * Try to create a publisher with no field.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithoutField()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher
+        m_publisher.removeAttribute(m_publisherField);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when no field is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.addAttribute(m_publisherField);
+        }
+    }
+
+    /**
+     * Try to create a publisher with an unexisting field.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithUnexistingField()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher and replace with an
+        // unexisting field name
+        m_publisher.removeAttribute(m_publisherField);
+        Attribute unexistingField = new Attribute("field", "m_unexistingField");
+        m_publisher.addAttribute(unexistingField);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when an unexisting field is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.removeAttribute(unexistingField);
+            m_publisher.addAttribute(m_publisherField);
+        }
+    }
+
+    /**
+     * Try to create a publisher with a bad typed field.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithBadTypedField()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher and replace with an
+        // bad typed field name
+        m_publisher.removeAttribute(m_publisherField);
+        Attribute badTypedField = new Attribute("field", "m_name");
+        m_publisher.addAttribute(badTypedField);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when an bad typed field is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.removeAttribute(badTypedField);
+            m_publisher.addAttribute(m_publisherField);
+        }
+    }
+
+    /**
+     * Try to create a publisher instance without topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithoutTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the publisher
+        m_publisher.removeAttribute(m_publisherTopics);
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        fact.start();
+
+        // Try to create an instance without specified topics
+        Dictionary conf = new Hashtable();
+        conf.put("instance.name", "provider without topics");
+
+        ComponentInstance instance;
+        try {
+            instance = fact.createComponentInstance(conf);
+            // Should not be executed
+            instance.dispose();
+            fail("The factory must not create instance without specified topics.");
+        } catch (ConfigurationException e) {
+            // OK
+        } finally {
+            fact.stop();
+            // Restore the original state of the publisher
+            m_publisher.addAttribute(m_publisherTopics);
+        }
+    }
+
+    /**
+     * Try to create a publisher with malformed topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithMalformedTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the publisher and replace with a
+        // malformed one
+        m_publisher.removeAttribute(m_publisherTopics);
+        Attribute malformedTopics = new Attribute("topics",
+                "| |\\| \\/ /-\\ |_ | |)");
+        m_publisher.addAttribute(malformedTopics);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when invalid topics are specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.removeAttribute(malformedTopics);
+            m_publisher.addAttribute(m_publisherTopics);
+        }
+    }
+
+    /**
+     * Try to create a publisher with a pattern topic (ending with '*') instead of a fixed topic.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithPatternTopic()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the publisher and replace with a
+        // malformed one
+        m_publisher.removeAttribute(m_publisherTopics);
+        Attribute malformedTopics = new Attribute("topics",
+                "a/pattern/topic/*");
+        m_publisher.addAttribute(malformedTopics);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when invalid topics are specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_publisher.removeAttribute(malformedTopics);
+            m_publisher.addAttribute(m_publisherTopics);
+        }
+    }
+
+    /**
+     * Try to create a publisher with malformed instance topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testPublisherWithMalformedInstanceTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the publisher and replace with a
+        // malformed one
+        m_publisher.removeAttribute(m_publisherTopics);
+        ComponentFactory fact = new ComponentFactory(bc, m_provider);
+        fact.start();
+
+        // Try to create an instance with malformed specified topics
+        Dictionary conf = new Hashtable();
+        conf.put("instance.name", "provider with malformed topics");
+        Dictionary topics = new Hashtable();
+        topics.put("donut-publisher", "| |\\| \\/ /-\\ |_ | |)");
+        conf.put("event.topics", topics);
+
+        ComponentInstance instance;
+        try {
+            instance = fact.createComponentInstance(conf);
+            // Should not be executed
+            instance.dispose();
+            fail("The factory must not create instance with invalid specified topics.");
+        } catch (ConfigurationException e) {
+            // OK
+        } finally {
+            fact.stop();
+            // Restore the original state of the publisher
+            m_publisher.addAttribute(m_publisherTopics);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with no name.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithoutName()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher
+        m_subscriber.removeAttribute(m_subscriberName);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when no name is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_subscriber.addAttribute(m_subscriberName);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with no callback.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithoutCallback()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the name attribute of the publisher
+        m_subscriber.removeAttribute(m_subscriberCallback);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when no callback is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the publisher
+            m_subscriber.addAttribute(m_subscriberCallback);
+        }
+    }
+
+    /**
+     * Try to create a subscriber instance without topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithoutTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the subscriber
+        m_subscriber.removeAttribute(m_subscriberTopics);
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        fact.start();
+
+        // Try to create an instance without specified topics
+        Dictionary conf = new Hashtable();
+        conf.put("instance.name", "consumer without topics");
+        conf.put("slow", "false");
+
+        ComponentInstance instance;
+        try {
+            instance = fact.createComponentInstance(conf);
+            // Should not be executed
+            instance.dispose();
+            fail("The factory must not create instance without specified topics.");
+        } catch (ConfigurationException e) {
+            // OK
+        } finally {
+            fact.stop();
+            // Restore the original state of the subscriber
+            m_subscriber.addAttribute(m_subscriberTopics);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with malformed topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithMalformedTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the subscriber and replace with a
+        // malformed one
+        m_subscriber.removeAttribute(m_subscriberTopics);
+        Attribute malformedTopics = new Attribute("topics",
+                "| |\\| \\/ /-\\ |_ | |)");
+        m_subscriber.addAttribute(malformedTopics);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when invalid topics are specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the subscriber
+            m_subscriber.removeAttribute(malformedTopics);
+            m_subscriber.addAttribute(m_subscriberTopics);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with malformed instance topics.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithMalformedInstanceTopics()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the topics attribute of the subscriber and replace with a
+        // malformed one
+        m_subscriber.removeAttribute(m_subscriberTopics);
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        fact.start();
+
+        // Try to create an instance with malformed specified topics
+        Dictionary conf = new Hashtable();
+        conf.put("instance.name", "consumer with malformed topics");
+        Dictionary topics = new Hashtable();
+        topics.put("donut-subscriber", "| |\\| \\/ /-\\ |_ | |)");
+        conf.put("event.topics", topics);
+
+        ComponentInstance instance;
+        try {
+            instance = fact.createComponentInstance(conf);
+            // Should not be executed
+            instance.dispose();
+            fail("The factory must not create instance with invalid specified topics.");
+        } catch (ConfigurationException e) {
+            // OK
+        } finally {
+            fact.stop();
+            // Restore the original state of the subscriber
+            m_subscriber.addAttribute(m_subscriberTopics);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with unknown data type.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithUnknownDataType()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the data-type attribute of the subscriber and replace with a
+        // malformed one
+        m_subscriber.removeAttribute(m_subscriberDataType);
+        Attribute unknownType = new Attribute("data-type", "org.unknown.Clazz");
+        m_subscriber.addAttribute(unknownType);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when unknown data type is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the subscriber
+            m_subscriber.removeAttribute(unknownType);
+            m_subscriber.addAttribute(m_subscriberDataType);
+        }
+    }
+
+    /**
+     * Try to create a subscriber with a data type that does not match with the
+     * callback parameter type.
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     */
+    @Test
+    public void testSubscriberWithUnappropriatedDataType()
+            throws ConfigurationException, MissingHandlerException,
+            UnacceptableConfiguration {
+
+        // Remove the data-type attribute of the subscriber and replace with a
+        // malformed one
+        m_subscriber.removeAttribute(m_subscriberDataType);
+        Attribute unknownType = new Attribute("data-type", "java.lang.String");
+        m_subscriber.addAttribute(unknownType);
+
+        // Create and try to start the factory
+        ComponentFactory fact = new ComponentFactory(bc, m_consumer);
+        try {
+            fact.start();
+            // Should not be executed
+            fact.stop();
+            fail("The factory must not start when unappropriated data type is specified.");
+        } catch (IllegalStateException e) {
+            // OK
+        } finally {
+            // Restore the original state of the subscriber
+            m_subscriber.removeAttribute(unknownType);
+            m_subscriber.addAttribute(m_subscriberDataType);
+        }
+    }
+
+    // DEBUG
+    public void dumpElement(String message, Element root) {
+        System.err.println(message + "\n" + dumpElement(0, root));
+    }
+
+    // DEBUG
+    private String dumpElement(int level, Element element) {
+        StringBuilder sb = new StringBuilder();
+        // Enter tag
+        for (int i = 0; i < level; i++) {
+            sb.append("  ");
+        }
+        sb.append('<');
+        sb.append(element.getName());
+        Attribute[] attributes = element.getAttributes();
+        for (int i = 0; i < attributes.length; i++) {
+            Attribute attribute = attributes[i];
+            sb.append(' ');
+            sb.append(attribute.getName());
+            sb.append('=');
+            sb.append(attribute.getValue());
+        }
+        sb.append(">\n");
+        // Children
+        Element[] elements = element.getElements();
+        for (int i = 0; i < elements.length; i++) {
+            sb.append(dumpElement(level + 1, elements[i]));
+        }
+        // Exit tag
+        for (int i = 0; i < level; i++) {
+            sb.append("  ");
+        }
+        sb.append("</" + element.getName() + ">\n");
+        return sb.toString();
+    }
+
+    /**
+     * Creates a subscriber listening on a pattern topic (ending with '*').
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened.
+     */
+    @Test
+    public void testSubscriberWithPatternTopic() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        Dictionary properties = new Hashtable();
+        Dictionary topics = new Hashtable();
+
+        // Create the donut consumer instance, listening on a pattern topic
+        properties.put("instance.name", "subscriber with pattern topic");
+        topics.put("donut-subscriber", "a/pattern/topic/*rf");
+        properties.put("event.topics", topics);
+        ComponentInstance instance = null;
+        try {
+            instance = m_utils.getDonutConsumerFactory()
+                    .createComponentInstance(properties);
+
+            // Should not been executed
+            instance.dispose();
+            fail("An invalid topic scope was accepted)");
+
+        } catch (ConfigurationException e) {
+            // Nothing to do
+        }
+
+        properties = new Hashtable();
+        topics = new Hashtable();
+
+        // Create the donut consumer instance, listening on a pattern topic
+        properties.put("instance.name", "subscriber with pattern topic");
+        topics.put("donut-subscriber", "a/pattern/*topic/rf");
+        properties.put("event.topics", topics);
+
+        try {
+            instance = m_utils.getDonutConsumerFactory()
+                    .createComponentInstance(properties);
+            instance.dispose();
+            fail("An invalid topic scope was accepted (2)");
+        } catch (ConfigurationException e) {
+            // Nothing to do
+        }
+    }
+
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandler.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandler.java
new file mode 100644
index 0000000..3814c1a
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandler.java
@@ -0,0 +1,714 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.EventTracker;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.event.Event;
+
+import java.util.*;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test the good behaviour of the EventAdminHandler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestEventAdminHandler extends Common {
+
+    /**
+     * The number of providers to test.
+     */
+    private static final int NUMBER_OF_PROVIDERS = 6;
+    /**
+     * The number of providers using the event admin handler to test.
+     */
+    private static final int NUMBER_OF_EAH_PROVIDERS = 4;
+    /**
+     * The number of consumers to test.
+     */
+    private static final int NUMBER_OF_CONSUMERS = 6;
+    /**
+     * The number of synchronous providers to test.
+     */
+    private static final int NUMBER_OF_SYNCHRONOUS_PROVIDERS = 3;
+    /**
+     * The number of slow consumers to test.
+     */
+    private static final int NUMBER_OF_QUICK_CONSUMERS = 3;
+    /**
+     * The list of topics to test.
+     */
+    private static final String[] TOPICS_LIST = {"foo", "bar", "nut",
+            "foo,bar", "bar,nut", "foo,nut", "foo,bar,nut"};
+    /**
+     * The utility class instance.
+     */
+    public EahTestUtils m_utils;
+    /**
+     * The providers' instances.
+     */
+    private ComponentInstance[] m_providersInstances;
+    /**
+     * The providers' service references.
+     */
+    private ServiceReference[] m_providersServices;
+    /**
+     * The providers' services.
+     */
+    private DonutProvider[] m_providers;
+    /**
+     * The synchronous providers' services.
+     */
+    private DonutProvider[] m_synchronousProviders;
+    /**
+     * The instances of providers that uses the event admin handler.
+     */
+    private ComponentInstance[] m_eahProvidersInstances;
+    /**
+     * The services of the providers that uses the event admin handler.
+     */
+    private DonutProvider[] m_eahProviders;
+    /**
+     * The synchronous donut event provider service.
+     */
+    private DonutProvider m_synchronousDonutEventProvider;
+    /**
+     * The consumers' instances.
+     */
+    private ComponentInstance[] m_consumersInstances;
+    /**
+     * The consumers' service references.
+     */
+    private ServiceReference[] m_consumersServices;
+    /**
+     * The consumers' services.
+     */
+    private DonutConsumer[] m_consumers;
+    /**
+     * The slow consumers' services.
+     */
+    private DonutConsumer[] m_quickConsumers;
+    /**
+     * The event tracker' instances.
+     */
+    private ComponentInstance m_eventTrackerInstance;
+    /**
+     * The event tracker' service references.
+     */
+    private ServiceReference m_eventTrackerService;
+    /**
+     * The event tracker service.
+     */
+    private EventTracker m_eventTracker;
+    /**
+     * The filtered consumers' instances.
+     */
+    private ComponentInstance[] m_filteredConsumersInstances;
+    /**
+     * The filtered consumers' service references.
+     */
+    private ServiceReference[] m_filteredConsumersServices;
+    /**
+     * The filtered consumers' services.
+     */
+    private DonutConsumer[] m_filteredConsumers;
+    /**
+     * The providers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsProvidersInstances;
+    /**
+     * The providers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsProvidersServices;
+    /**
+     * The providers' service with specified topics.
+     */
+    private DonutProvider[] m_topicsProviders;
+    /**
+     * The provider that send donuts on the "foo" topic.
+     */
+    private DonutProvider m_fooProvider;
+    /**
+     * The provider that send donuts on the "bar" topic.
+     */
+    private DonutProvider m_barProvider;
+    /**
+     * The provider that send donuts on the "nut" topic.
+     */
+    private DonutProvider m_nutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar" topics.
+     */
+    private DonutProvider m_fooBarProvider;
+    /**
+     * The provider that send donuts on the "bar,nut" topics.
+     */
+    private DonutProvider m_barNutProvider;
+    /**
+     * The provider that send donuts on the "foo,nut" topics.
+     */
+    private DonutProvider m_fooNutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar,nut" topics.
+     */
+    private DonutProvider m_fooBarNutProvider;
+    /**
+     * The consumers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsConsumersInstances;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsConsumersServices;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private DonutConsumer[] m_topicsConsumers;
+    /**
+     * The consumer that receive donuts on the "foo" topic.
+     */
+    private DonutConsumer m_fooConsumer;
+    /**
+     * The consumer that receive donuts on the "bar" topic.
+     */
+    private DonutConsumer m_barConsumer;
+    /**
+     * The consumer that receive donuts on the "nut" topic.
+     */
+    private DonutConsumer m_nutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar" topics.
+     */
+    private DonutConsumer m_fooBarConsumer;
+    /**
+     * The consumer that receive donuts on the "bar,nut" topics.
+     */
+    private DonutConsumer m_barNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,nut" topics.
+     */
+    private DonutConsumer m_fooNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar,nut" topics.
+     */
+    private DonutConsumer m_fooBarNutConsumer;
+
+    /**
+     * Initialization before test cases.
+     * <p/>
+     * Create all the instances
+     *
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     */
+    @Before
+    public void setUp()
+            throws UnacceptableConfiguration, MissingHandlerException,
+            ConfigurationException {
+
+        m_utils = new EahTestUtils(bc, ipojoHelper);
+        Dictionary properties = new Hashtable();
+
+        // All the providers
+        m_providersInstances = new ComponentInstance[NUMBER_OF_PROVIDERS];
+        m_providersServices = new ServiceReference[NUMBER_OF_PROVIDERS];
+        m_providers = new DonutProvider[NUMBER_OF_PROVIDERS];
+        m_synchronousProviders = new DonutProvider[NUMBER_OF_SYNCHRONOUS_PROVIDERS];
+        m_eahProviders = new DonutProvider[NUMBER_OF_EAH_PROVIDERS];
+        m_eahProvidersInstances = new ComponentInstance[NUMBER_OF_EAH_PROVIDERS];
+        m_topicsProvidersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsProvidersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsProviders = new DonutProvider[TOPICS_LIST.length];
+
+        // Create the (asynchronous) donut provider
+        properties.put("instance.name", "asynchronous donut provider");
+        m_providersInstances[0] = m_utils.getDonutProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut provider");
+        m_providersInstances[1] = m_utils.getSynchronousDonutProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous donut event provider");
+        m_providersInstances[2] = m_utils.getDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut event provider");
+        m_providersInstances[3] = m_utils
+                .getSynchronousDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous event provider");
+        m_providersInstances[4] = m_utils.getEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous event provider");
+        m_providersInstances[5] = m_utils.getSynchronousEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            m_providersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutProvider.class.getName(),
+                    m_providersInstances[i].getInstanceName());
+            m_providers[i] = (DonutProvider) bc
+                    .getService(m_providersServices[i]);
+        }
+        m_synchronousProviders[0] = m_providers[1];
+        m_synchronousProviders[1] = m_providers[3];
+        m_synchronousProviders[2] = m_providers[5];
+        m_eahProviders[0] = m_providers[0];
+        m_eahProviders[1] = m_providers[1];
+        m_eahProviders[2] = m_providers[2];
+        m_eahProviders[3] = m_providers[3];
+        m_eahProvidersInstances[0] = m_providersInstances[0];
+        m_eahProvidersInstances[1] = m_providersInstances[1];
+        m_eahProvidersInstances[2] = m_providersInstances[2];
+        m_eahProvidersInstances[3] = m_providersInstances[3];
+        m_synchronousDonutEventProvider = m_providers[3];
+
+        // All the consumers
+        m_consumersInstances = new ComponentInstance[NUMBER_OF_CONSUMERS];
+        m_consumersServices = new ServiceReference[NUMBER_OF_CONSUMERS];
+        m_consumers = new DonutConsumer[NUMBER_OF_CONSUMERS];
+        m_quickConsumers = new DonutConsumer[NUMBER_OF_QUICK_CONSUMERS];
+        m_filteredConsumersInstances = new ComponentInstance[Donut.FLAVOURS.length];
+        m_filteredConsumersServices = new ServiceReference[Donut.FLAVOURS.length];
+        m_filteredConsumers = new DonutConsumer[Donut.FLAVOURS.length];
+        m_topicsConsumersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsConsumersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsConsumers = new DonutConsumer[TOPICS_LIST.length];
+
+        // Create the (quick) donut consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut consumer");
+        m_consumersInstances[0] = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut event consumer");
+        m_consumersInstances[1] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick event consumer");
+        m_consumersInstances[2] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut consumer
+        properties = new Hashtable();
+        properties.put("slow", Boolean.TRUE);
+        properties.put("instance.name", "slow donut consumer");
+        m_consumersInstances[3] = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow donut event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[4] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[5] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutConsumer.class.getName(),
+                    m_consumersInstances[i].getInstanceName());
+            m_consumers[i] = (DonutConsumer) bc
+                    .getService(m_consumersServices[i]);
+        }
+        m_quickConsumers[0] = m_consumers[0];
+        m_quickConsumers[1] = m_consumers[1];
+        m_quickConsumers[2] = m_consumers[2];
+
+        // Create the event tracker
+        properties = new Hashtable();
+        properties.put("instance.name", "event tracker");
+        m_eventTrackerInstance = m_utils.getEventTrackerFactory()
+                .createComponentInstance(properties);
+        m_eventTrackerService = ipojoHelper.getServiceReferenceByName(
+                EventTracker.class.getName(), m_eventTrackerInstance
+                .getInstanceName());
+        m_eventTracker = (EventTracker) bc
+                .getService(m_eventTrackerService);
+
+        // Create the filtered consumer
+        Dictionary filter = new Hashtable();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            String flavour = Donut.FLAVOURS[i];
+            properties = new Hashtable();
+            filter.put("donut-event-subscriber", "(flavour=" + flavour + ")");
+            properties.put("instance.name", flavour + " donut consumer");
+            properties.put("event.filter", filter);
+            m_filteredConsumersInstances[i] = m_utils
+                    .getDonutEventConsumerFactory().createComponentInstance(
+                            properties);
+            m_filteredConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(
+                            DonutConsumer.class
+                                    .getName(), m_filteredConsumersInstances[i]
+                            .getInstanceName());
+            m_filteredConsumers[i] = (DonutConsumer) bc
+                    .getService(m_filteredConsumersServices[i]);
+        }
+
+        // Create the providers and consumers selling and receiving donuts on
+        // specific topics
+        Dictionary topics = new Hashtable();
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            String topicsString = TOPICS_LIST[i];
+            properties = new Hashtable();
+            // Create provider
+            topics.put("donut-publisher", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut provider");
+            m_topicsProvidersInstances[i] = m_utils
+                    .getSynchronousDonutProviderFactory()
+                    .createComponentInstance(properties);
+            m_topicsProvidersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutProvider.class
+                            .getName(), m_topicsProvidersInstances[i]
+                            .getInstanceName());
+            m_topicsProviders[i] = (DonutProvider) bc
+                    .getService(m_topicsProvidersServices[i]);
+
+            // Create consumer
+            properties = new Hashtable();
+            topics.put("donut-subscriber", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut consumer");
+
+            m_topicsConsumersInstances[i] = m_utils.getDonutConsumerFactory()
+                    .createComponentInstance(properties);
+            m_topicsConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutConsumer.class
+                            .getName(), m_topicsConsumersInstances[i]
+                            .getInstanceName());
+            m_topicsConsumers[i] = (DonutConsumer) bc
+                    .getService(m_topicsConsumersServices[i]);
+            topics.remove("donut-subscriber");
+        }
+
+        m_fooProvider = m_topicsProviders[0];
+        m_barProvider = m_topicsProviders[1];
+        m_nutProvider = m_topicsProviders[2];
+        m_fooBarProvider = m_topicsProviders[3];
+        m_barNutProvider = m_topicsProviders[4];
+        m_fooNutProvider = m_topicsProviders[5];
+        m_fooBarNutProvider = m_topicsProviders[6];
+        m_fooConsumer = m_topicsConsumers[0];
+        m_barConsumer = m_topicsConsumers[1];
+        m_nutConsumer = m_topicsConsumers[2];
+        m_fooBarConsumer = m_topicsConsumers[3];
+        m_barNutConsumer = m_topicsConsumers[4];
+        m_fooNutConsumer = m_topicsConsumers[5];
+        m_fooBarNutConsumer = m_topicsConsumers[6];
+
+    }
+
+    /**
+     * Creates a subscriber listening on a pattern topic (ending with '*').
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened.
+     */
+    @Test
+    public void testSubscriberWithPatternTopic() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        Dictionary properties = new Hashtable();
+        Dictionary topics = new Hashtable();
+
+        // Create the donut consumer instance, listening on a pattern topic
+        properties.put("instance.name", "subscriber with pattern topic");
+        topics.put("donut-subscriber", "a/pattern/topic/*");
+        properties.put("event.topics", topics);
+
+        ComponentInstance instance = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+        instance.dispose();
+    }
+
+    /**
+     * Test the event handler reliability by sending events with all kinds of
+     * publisher and check they are received by all kinds of subscriber.
+     */
+    @Test
+    public void testReliability() {
+
+        // Flush donut list for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumers[i].clearDonuts();
+        }
+
+        // Send a lot of donut with each provider
+        List sentDonuts = new ArrayList(NUMBER_OF_PROVIDERS
+                * EahTestUtils.NUMBER_OF_TESTS);
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+                sentDonuts.add(m_providers[i].sellDonut());
+            }
+        }
+
+        // Wait a respectable amount of time
+        EahTestUtils.sleep(EahTestUtils.BLACK_LIST_TIME
+                + EahTestUtils.A_LONG_TIME);
+
+        // Collect all received donuts for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            List receivedDonuts = Arrays.asList(m_consumers[i].getAllDonuts());
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts.",
+                    sentDonuts.size(), receivedDonuts.size());
+            assertTrue("The receiver must have eaten all sent donuts.",
+                    receivedDonuts.containsAll(sentDonuts));
+        }
+    }
+
+    /**
+     * Test the synchronism of event sending for the component.
+     * <p/>
+     * This test consists to send synchronously a big amount of donuts and to
+     * check immediately if it has been received (by all quick consumers).
+     */
+    @Test
+    public void testSynchronism() {
+
+        // Flush donut list for quick consumers
+        for (int i = 0; i < NUMBER_OF_QUICK_CONSUMERS; i++) {
+            m_quickConsumers[i].clearDonuts();
+        }
+
+        // Send a lot of donuts and check they are immediately received.
+        Donut sentDonut;
+        Donut receivedDonut;
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            for (int j = 0; j < NUMBER_OF_SYNCHRONOUS_PROVIDERS; j++) {
+                sentDonut = m_synchronousProviders[j].sellDonut();
+                for (int k = 0; k < NUMBER_OF_QUICK_CONSUMERS; k++) {
+                    receivedDonut = m_quickConsumers[k].getDonut();
+                    assertEquals(
+                            "The donut must have been received immediately and be the be the same as the sent one.",
+                            sentDonut, receivedDonut);
+                }
+            }
+        }
+    }
+
+    /**
+     * Test that the received events contains the instance name of the sender.
+     */
+    @Test
+    public void testInstanceName() {
+
+        // Flush event list of the event tracker
+        m_eventTracker.clearEvents();
+
+        // Send donuts and check the sender instance name
+        Event receivedEvent;
+        for (int i = 0; i < NUMBER_OF_EAH_PROVIDERS; i++) {
+            m_eahProviders[i].sellDonut();
+            receivedEvent = m_eventTracker.waitForEvent();
+            assertEquals(
+                    "The instance name property of the received message must be the same as the sender instance name.",
+                    m_eahProvidersInstances[i].getInstanceName(), receivedEvent
+                    .getProperty("publisher.instance.name"));
+        }
+    }
+
+    /**
+     * Test the event filtering.
+     * <p/>
+     * This test send donuts with different flavours. Each filtered consumer
+     * must receive only a certain kind of donut. Of course, all donuts must
+     * have been received too.
+     */
+    @Test
+    public void testFilters() {
+
+        // The sent donuts, sorted by flavour
+        List[] sentDonuts = new List[Donut.FLAVOURS.length];
+
+        // Flush donut list for each filtered consumer
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            m_filteredConsumers[i].clearDonuts();
+            sentDonuts[i] = new ArrayList(EahTestUtils.NUMBER_OF_TESTS
+                    / Donut.FLAVOURS.length);
+        }
+
+        // Send donuts
+        for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+            Donut donut = m_synchronousDonutEventProvider.sellDonut();
+            sentDonuts[EahTestUtils.flavourIndex(donut.getFlavour())]
+                    .add(donut);
+        }
+
+        // Check the received donuts
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            Donut[] receivedDonuts = m_filteredConsumers[i].getAllDonuts();
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts with the matching flavour.",
+                    sentDonuts[i].size(), receivedDonuts.length);
+            assertTrue(
+                    "The receiver must have eaten all sent donuts matching the wanted flavour.",
+                    Arrays.asList(receivedDonuts).containsAll(sentDonuts[i]));
+        }
+
+    }
+
+    /**
+     * Test the event topic.
+     * <p/>
+     * This test send donuts on several topics. Each consumer (who listens to
+     * one or several topics) must receive donuts sent on his specifics topics.
+     */
+    @Test
+    public void testTopics() {
+
+        // The sent donuts, sorted by topic
+        int foos = 0;
+        int bars = 0;
+        int nuts = 0;
+
+        // Flush consumers
+        m_fooConsumer.clearDonuts();
+        m_barConsumer.clearDonuts();
+        m_nutConsumer.clearDonuts();
+        m_fooBarConsumer.clearDonuts();
+        m_barNutConsumer.clearDonuts();
+        m_fooNutConsumer.clearDonuts();
+        m_fooBarNutConsumer.clearDonuts();
+
+        // Send donuts
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            m_fooProvider.sellDonut();
+            foos++;
+
+            m_barProvider.sellDonut();
+            bars++;
+
+            m_nutProvider.sellDonut();
+            nuts++;
+
+            m_fooBarProvider.sellDonut();
+            foos++;
+            bars++;
+
+            m_barNutProvider.sellDonut();
+            bars++;
+            nuts++;
+
+            m_fooNutProvider.sellDonut();
+            foos++;
+            nuts++;
+
+            m_fooBarNutProvider.sellDonut();
+            foos++;
+            bars++;
+            nuts++;
+        }
+
+        // Check received donuts
+        assertEquals("The number of received donuts must be correct.", foos,
+                m_fooConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars,
+                m_barConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", nuts,
+                m_nutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars, m_fooBarConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars
+                + nuts, m_barNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + nuts, m_fooNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars + nuts, m_fooBarNutConsumer.getAllDonuts().length);
+
+    }
+
+    /**
+     * Finalization after test cases.
+     * <p/>
+     * Release all services references and destroy instances.
+     */
+    @After
+    public void tearDown() {
+        int index;
+        for (index = 0; index < NUMBER_OF_PROVIDERS; index++) {
+            bc.ungetService(m_providersServices[index]);
+            m_providersInstances[index].dispose();
+        }
+        for (index = 0; index < NUMBER_OF_CONSUMERS; index++) {
+            bc.ungetService(m_consumersServices[index]);
+            m_consumersInstances[index].dispose();
+        }
+        bc.ungetService(m_eventTrackerService);
+        m_eventTrackerInstance.dispose();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            bc.ungetService(m_filteredConsumersServices[i]);
+            m_filteredConsumersInstances[i].dispose();
+        }
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            bc.ungetService(m_topicsProvidersServices[i]);
+            m_topicsProvidersInstances[i].dispose();
+            bc.ungetService(m_topicsConsumersServices[i]);
+            m_topicsConsumersInstances[i].dispose();
+        }
+
+    }
+
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandlerWithNewAttributes.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandlerWithNewAttributes.java
new file mode 100644
index 0000000..d7f6b57
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestEventAdminHandlerWithNewAttributes.java
@@ -0,0 +1,714 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.EventTracker;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.event.Event;
+
+import java.util.*;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test the good behaviour of the EventAdminHandler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestEventAdminHandlerWithNewAttributes extends Common {
+
+    /**
+     * The number of providers to test.
+     */
+    private static final int NUMBER_OF_PROVIDERS = 6;
+    /**
+     * The number of providers using the event admin handler to test.
+     */
+    private static final int NUMBER_OF_EAH_PROVIDERS = 4;
+    /**
+     * The number of consumers to test.
+     */
+    private static final int NUMBER_OF_CONSUMERS = 6;
+    /**
+     * The number of synchronous providers to test.
+     */
+    private static final int NUMBER_OF_SYNCHRONOUS_PROVIDERS = 3;
+    /**
+     * The number of slow consumers to test.
+     */
+    private static final int NUMBER_OF_QUICK_CONSUMERS = 3;
+    /**
+     * The list of topics to test.
+     */
+    private static final String[] TOPICS_LIST = {"foo", "bar", "nut",
+            "foo,bar", "bar,nut", "foo,nut", "foo,bar,nut"};
+    /**
+     * The utility class instance.
+     */
+    public EahTestUtils m_utils;
+    /**
+     * The providers' instances.
+     */
+    private ComponentInstance[] m_providersInstances;
+    /**
+     * The providers' service references.
+     */
+    private ServiceReference[] m_providersServices;
+    /**
+     * The providers' services.
+     */
+    private DonutProvider[] m_providers;
+    /**
+     * The synchronous providers' services.
+     */
+    private DonutProvider[] m_synchronousProviders;
+    /**
+     * The instances of providers that uses the event admin handler.
+     */
+    private ComponentInstance[] m_eahProvidersInstances;
+    /**
+     * The services of the providers that uses the event admin handler.
+     */
+    private DonutProvider[] m_eahProviders;
+    /**
+     * The synchronous donut event provider service.
+     */
+    private DonutProvider m_synchronousDonutEventProvider;
+    /**
+     * The consumers' instances.
+     */
+    private ComponentInstance[] m_consumersInstances;
+    /**
+     * The consumers' service references.
+     */
+    private ServiceReference[] m_consumersServices;
+    /**
+     * The consumers' services.
+     */
+    private DonutConsumer[] m_consumers;
+    /**
+     * The slow consumers' services.
+     */
+    private DonutConsumer[] m_quickConsumers;
+    /**
+     * The event tracker' instances.
+     */
+    private ComponentInstance m_eventTrackerInstance;
+    /**
+     * The event tracker' service references.
+     */
+    private ServiceReference m_eventTrackerService;
+    /**
+     * The event tracker service.
+     */
+    private EventTracker m_eventTracker;
+    /**
+     * The filtered consumers' instances.
+     */
+    private ComponentInstance[] m_filteredConsumersInstances;
+    /**
+     * The filtered consumers' service references.
+     */
+    private ServiceReference[] m_filteredConsumersServices;
+    /**
+     * The filtered consumers' services.
+     */
+    private DonutConsumer[] m_filteredConsumers;
+    /**
+     * The providers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsProvidersInstances;
+    /**
+     * The providers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsProvidersServices;
+    /**
+     * The providers' service with specified topics.
+     */
+    private DonutProvider[] m_topicsProviders;
+    /**
+     * The provider that send donuts on the "foo" topic.
+     */
+    private DonutProvider m_fooProvider;
+    /**
+     * The provider that send donuts on the "bar" topic.
+     */
+    private DonutProvider m_barProvider;
+    /**
+     * The provider that send donuts on the "nut" topic.
+     */
+    private DonutProvider m_nutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar" topics.
+     */
+    private DonutProvider m_fooBarProvider;
+    /**
+     * The provider that send donuts on the "bar,nut" topics.
+     */
+    private DonutProvider m_barNutProvider;
+    /**
+     * The provider that send donuts on the "foo,nut" topics.
+     */
+    private DonutProvider m_fooNutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar,nut" topics.
+     */
+    private DonutProvider m_fooBarNutProvider;
+    /**
+     * The consumers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsConsumersInstances;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsConsumersServices;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private DonutConsumer[] m_topicsConsumers;
+    /**
+     * The consumer that receive donuts on the "foo" topic.
+     */
+    private DonutConsumer m_fooConsumer;
+    /**
+     * The consumer that receive donuts on the "bar" topic.
+     */
+    private DonutConsumer m_barConsumer;
+    /**
+     * The consumer that receive donuts on the "nut" topic.
+     */
+    private DonutConsumer m_nutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar" topics.
+     */
+    private DonutConsumer m_fooBarConsumer;
+    /**
+     * The consumer that receive donuts on the "bar,nut" topics.
+     */
+    private DonutConsumer m_barNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,nut" topics.
+     */
+    private DonutConsumer m_fooNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar,nut" topics.
+     */
+    private DonutConsumer m_fooBarNutConsumer;
+
+    /**
+     * Initialization before test cases.
+     * <p/>
+     * Create all the instances
+     *
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     */
+    @Before
+    public void setUp()
+            throws UnacceptableConfiguration, MissingHandlerException,
+            ConfigurationException {
+
+        m_utils = new EahTestUtils(bc, ipojoHelper);
+        Dictionary properties = new Hashtable();
+
+        // All the providers
+        m_providersInstances = new ComponentInstance[NUMBER_OF_PROVIDERS];
+        m_providersServices = new ServiceReference[NUMBER_OF_PROVIDERS];
+        m_providers = new DonutProvider[NUMBER_OF_PROVIDERS];
+        m_synchronousProviders = new DonutProvider[NUMBER_OF_SYNCHRONOUS_PROVIDERS];
+        m_eahProviders = new DonutProvider[NUMBER_OF_EAH_PROVIDERS];
+        m_eahProvidersInstances = new ComponentInstance[NUMBER_OF_EAH_PROVIDERS];
+        m_topicsProvidersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsProvidersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsProviders = new DonutProvider[TOPICS_LIST.length];
+
+        // Create the (asynchronous) donut provider
+        properties.put("instance.name", "asynchronous donut provider");
+        m_providersInstances[0] = m_utils.getDonutProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut provider");
+        m_providersInstances[1] = m_utils.getSynchronousDonutProvider2Factory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous donut event provider");
+        m_providersInstances[2] = m_utils.getDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut event provider");
+        m_providersInstances[3] = m_utils
+                .getSynchronousDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous event provider");
+        m_providersInstances[4] = m_utils.getEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous event provider");
+        m_providersInstances[5] = m_utils.getSynchronousEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            m_providersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutProvider.class.getName(),
+                    m_providersInstances[i].getInstanceName());
+            m_providers[i] = (DonutProvider) bc
+                    .getService(m_providersServices[i]);
+        }
+        m_synchronousProviders[0] = m_providers[1];
+        m_synchronousProviders[1] = m_providers[3];
+        m_synchronousProviders[2] = m_providers[5];
+        m_eahProviders[0] = m_providers[0];
+        m_eahProviders[1] = m_providers[1];
+        m_eahProviders[2] = m_providers[2];
+        m_eahProviders[3] = m_providers[3];
+        m_eahProvidersInstances[0] = m_providersInstances[0];
+        m_eahProvidersInstances[1] = m_providersInstances[1];
+        m_eahProvidersInstances[2] = m_providersInstances[2];
+        m_eahProvidersInstances[3] = m_providersInstances[3];
+        m_synchronousDonutEventProvider = m_providers[3];
+
+        // All the consumers
+        m_consumersInstances = new ComponentInstance[NUMBER_OF_CONSUMERS];
+        m_consumersServices = new ServiceReference[NUMBER_OF_CONSUMERS];
+        m_consumers = new DonutConsumer[NUMBER_OF_CONSUMERS];
+        m_quickConsumers = new DonutConsumer[NUMBER_OF_QUICK_CONSUMERS];
+
+        m_filteredConsumersInstances = new ComponentInstance[Donut.FLAVOURS.length];
+        m_filteredConsumersServices = new ServiceReference[Donut.FLAVOURS.length];
+        m_filteredConsumers = new DonutConsumer[Donut.FLAVOURS.length];
+        m_topicsConsumersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsConsumersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsConsumers = new DonutConsumer[TOPICS_LIST.length];
+
+        // Create the (quick) donut consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut consumer");
+        m_consumersInstances[0] = m_utils.getDonutConsumer2Factory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut event consumer");
+        m_consumersInstances[1] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick event consumer");
+        m_consumersInstances[2] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut consumer
+        properties = new Hashtable();
+        properties.put("slow", Boolean.TRUE);
+        properties.put("instance.name", "slow donut consumer");
+        m_consumersInstances[3] = m_utils.getDonutConsumer2Factory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow donut event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[4] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[5] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutConsumer.class.getName(),
+                    m_consumersInstances[i].getInstanceName());
+            m_consumers[i] = (DonutConsumer) bc
+                    .getService(m_consumersServices[i]);
+        }
+        m_quickConsumers[0] = m_consumers[0];
+        m_quickConsumers[1] = m_consumers[1];
+        m_quickConsumers[2] = m_consumers[2];
+
+        // Create the event tracker
+        properties = new Hashtable();
+        properties.put("instance.name", "event tracker");
+        m_eventTrackerInstance = m_utils.getEventTrackerFactory()
+                .createComponentInstance(properties);
+        m_eventTrackerService = ipojoHelper.getServiceReferenceByName(
+                EventTracker.class.getName(), m_eventTrackerInstance
+                .getInstanceName());
+        m_eventTracker = (EventTracker) bc
+                .getService(m_eventTrackerService);
+
+        // Create the filtered consumer
+        Dictionary filter = new Hashtable();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            String flavour = Donut.FLAVOURS[i];
+            properties = new Hashtable();
+            filter.put("donut-event-subscriber", "(flavour=" + flavour + ")");
+            properties.put("instance.name", flavour + " donut consumer");
+            properties.put("event.filter", filter);
+            m_filteredConsumersInstances[i] = m_utils
+                    .getDonutEventConsumerFactory().createComponentInstance(
+                            properties);
+            m_filteredConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutConsumer.class
+                            .getName(), m_filteredConsumersInstances[i]
+                            .getInstanceName());
+            m_filteredConsumers[i] = (DonutConsumer) bc
+                    .getService(m_filteredConsumersServices[i]);
+        }
+
+        // Create the providers and consumers selling and receiving donuts on
+        // specific topics
+        Dictionary topics = new Hashtable();
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            String topicsString = TOPICS_LIST[i];
+            properties = new Hashtable();
+            // Create provider
+            topics.put("donut-publisher", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut provider");
+            m_topicsProvidersInstances[i] = m_utils
+                    .getSynchronousDonutProviderFactory()
+                    .createComponentInstance(properties);
+            m_topicsProvidersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutProvider.class
+                            .getName(), m_topicsProvidersInstances[i]
+                            .getInstanceName());
+            m_topicsProviders[i] = (DonutProvider) bc
+                    .getService(m_topicsProvidersServices[i]);
+
+            // Create consumer
+            properties = new Hashtable();
+            topics.put("donut-subscriber", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut consumer");
+
+            m_topicsConsumersInstances[i] = m_utils.getDonutConsumer2Factory()
+                    .createComponentInstance(properties);
+            m_topicsConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutConsumer.class
+                            .getName(), m_topicsConsumersInstances[i]
+                            .getInstanceName());
+            m_topicsConsumers[i] = (DonutConsumer) bc
+                    .getService(m_topicsConsumersServices[i]);
+            topics.remove("donut-subscriber");
+        }
+
+        m_fooProvider = m_topicsProviders[0];
+        m_barProvider = m_topicsProviders[1];
+        m_nutProvider = m_topicsProviders[2];
+        m_fooBarProvider = m_topicsProviders[3];
+        m_barNutProvider = m_topicsProviders[4];
+        m_fooNutProvider = m_topicsProviders[5];
+        m_fooBarNutProvider = m_topicsProviders[6];
+        m_fooConsumer = m_topicsConsumers[0];
+        m_barConsumer = m_topicsConsumers[1];
+        m_nutConsumer = m_topicsConsumers[2];
+        m_fooBarConsumer = m_topicsConsumers[3];
+        m_barNutConsumer = m_topicsConsumers[4];
+        m_fooNutConsumer = m_topicsConsumers[5];
+        m_fooBarNutConsumer = m_topicsConsumers[6];
+
+    }
+
+    /**
+     * Creates a subscriber listening on a pattern topic (ending with '*').
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened.
+     */
+    @Test
+    public void testSubscriberWithPatternTopic() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        Dictionary properties = new Hashtable();
+        Dictionary topics = new Hashtable();
+
+        // Create the donut consumer instance, listening on a pattern topic
+        properties.put("instance.name", "subscriber with pattern topic");
+        topics.put("donut-subscriber", "a/pattern/topic/*");
+        properties.put("event.topics", topics);
+
+        ComponentInstance instance = m_utils.getDonutConsumer2Factory()
+                .createComponentInstance(properties);
+        instance.dispose();
+    }
+
+    /**
+     * Test the event handler reliability by sending events with all kinds of
+     * publisher and check they are received by all kinds of subscriber.
+     */
+    @Test
+    public void testReliability() {
+
+        // Flush donut list for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumers[i].clearDonuts();
+        }
+
+        // Send a lot of donut with each provider
+        List sentDonuts = new ArrayList(NUMBER_OF_PROVIDERS
+                * EahTestUtils.NUMBER_OF_TESTS);
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+                sentDonuts.add(m_providers[i].sellDonut());
+            }
+        }
+
+        // Wait a respectable amount of time
+        EahTestUtils.sleep(EahTestUtils.BLACK_LIST_TIME
+                + EahTestUtils.A_LONG_TIME);
+
+        // Collect all received donuts for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            List receivedDonuts = Arrays.asList(m_consumers[i].getAllDonuts());
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts.",
+                    sentDonuts.size(), receivedDonuts.size());
+            assertTrue("The receiver must have eaten all sent donuts.",
+                    receivedDonuts.containsAll(sentDonuts));
+        }
+    }
+
+    /**
+     * Test the synchronism of event sending for the component.
+     * <p/>
+     * This test consists to send synchronously a big amount of donuts and to
+     * check immediately if it has been received (by all quick consumers).
+     */
+    @Test
+    public void testSynchronism() {
+
+        // Flush donut list for quick consumers
+        for (int i = 0; i < NUMBER_OF_QUICK_CONSUMERS; i++) {
+            m_quickConsumers[i].clearDonuts();
+        }
+
+        // Send a lot of donuts and check they are immediately received.
+        Donut sentDonut;
+        Donut receivedDonut;
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            for (int j = 0; j < NUMBER_OF_SYNCHRONOUS_PROVIDERS; j++) {
+                sentDonut = m_synchronousProviders[j].sellDonut();
+                for (int k = 0; k < NUMBER_OF_QUICK_CONSUMERS; k++) {
+                    receivedDonut = m_quickConsumers[k].getDonut();
+                    assertEquals(
+                            "The donut must have been received immediately and be the be the same as the sent one.",
+                            sentDonut, receivedDonut);
+                }
+            }
+        }
+    }
+
+    /**
+     * Test that the received events contains the instance name of the sender.
+     */
+    @Test
+    public void testInstanceName() {
+
+        // Flush event list of the event tracker
+        m_eventTracker.clearEvents();
+
+        // Send donuts and check the sender instance name
+        Event receivedEvent;
+        for (int i = 0; i < NUMBER_OF_EAH_PROVIDERS; i++) {
+            m_eahProviders[i].sellDonut();
+            receivedEvent = m_eventTracker.waitForEvent();
+            assertEquals(
+                    "The instance name property of the received message must be the same as the sender instance name.",
+                    m_eahProvidersInstances[i].getInstanceName(), receivedEvent
+                    .getProperty("publisher.instance.name"));
+        }
+    }
+
+    /**
+     * Test the event filtering.
+     * <p/>
+     * This test send donuts with different flavours. Each filtered consumer
+     * must receive only a certain kind of donut. Of course, all donuts must
+     * have been received too.
+     */
+    @Test
+    public void testFilters() {
+
+        // The sent donuts, sorted by flavour
+        List[] sentDonuts = new List[Donut.FLAVOURS.length];
+
+        // Flush donut list for each filtered consumer
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            m_filteredConsumers[i].clearDonuts();
+            sentDonuts[i] = new ArrayList(EahTestUtils.NUMBER_OF_TESTS
+                    / Donut.FLAVOURS.length);
+        }
+
+        // Send donuts
+        for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+            Donut donut = m_synchronousDonutEventProvider.sellDonut();
+            sentDonuts[EahTestUtils.flavourIndex(donut.getFlavour())]
+                    .add(donut);
+        }
+
+        // Check the received donuts
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            Donut[] receivedDonuts = m_filteredConsumers[i].getAllDonuts();
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts with the matching flavour.",
+                    sentDonuts[i].size(), receivedDonuts.length);
+            assertTrue(
+                    "The receiver must have eaten all sent donuts matching the wanted flavour.",
+                    Arrays.asList(receivedDonuts).containsAll(sentDonuts[i]));
+        }
+
+    }
+
+    /**
+     * Test the event topic.
+     * <p/>
+     * This test send donuts on several topics. Each consumer (who listens to
+     * one or several topics) must receive donuts sent on his specifics topics.
+     */
+    @Test
+    public void testTopics() {
+
+        // The sent donuts, sorted by topic
+        int foos = 0;
+        int bars = 0;
+        int nuts = 0;
+
+        // Flush consumers
+        m_fooConsumer.clearDonuts();
+        m_barConsumer.clearDonuts();
+        m_nutConsumer.clearDonuts();
+        m_fooBarConsumer.clearDonuts();
+        m_barNutConsumer.clearDonuts();
+        m_fooNutConsumer.clearDonuts();
+        m_fooBarNutConsumer.clearDonuts();
+
+        // Send donuts
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            m_fooProvider.sellDonut();
+            foos++;
+
+            m_barProvider.sellDonut();
+            bars++;
+
+            m_nutProvider.sellDonut();
+            nuts++;
+
+            m_fooBarProvider.sellDonut();
+            foos++;
+            bars++;
+
+            m_barNutProvider.sellDonut();
+            bars++;
+            nuts++;
+
+            m_fooNutProvider.sellDonut();
+            foos++;
+            nuts++;
+
+            m_fooBarNutProvider.sellDonut();
+            foos++;
+            bars++;
+            nuts++;
+        }
+
+        // Check received donuts
+        assertEquals("The number of received donuts must be correct.", foos,
+                m_fooConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars,
+                m_barConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", nuts,
+                m_nutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars, m_fooBarConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars
+                + nuts, m_barNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + nuts, m_fooNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars + nuts, m_fooBarNutConsumer.getAllDonuts().length);
+
+    }
+
+    /**
+     * Finalization after test cases.
+     * <p/>
+     * Release all services references and destroy instances.
+     */
+    @After
+    public void tearDown() {
+        int index;
+        for (index = 0; index < NUMBER_OF_PROVIDERS; index++) {
+            bc.ungetService(m_providersServices[index]);
+            m_providersInstances[index].dispose();
+        }
+        for (index = 0; index < NUMBER_OF_CONSUMERS; index++) {
+            bc.ungetService(m_consumersServices[index]);
+            m_consumersInstances[index].dispose();
+        }
+        bc.ungetService(m_eventTrackerService);
+        m_eventTrackerInstance.dispose();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            bc.ungetService(m_filteredConsumersServices[i]);
+            m_filteredConsumersInstances[i].dispose();
+        }
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            bc.ungetService(m_topicsProvidersServices[i]);
+            m_topicsProvidersInstances[i].dispose();
+            bc.ungetService(m_topicsConsumersServices[i]);
+            m_topicsConsumersInstances[i].dispose();
+        }
+
+    }
+
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestPublisher.java b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestPublisher.java
new file mode 100644
index 0000000..950405b
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler-it/src/it/event-admin-it/src/test/java/org/apache/felix/ipojo/handler/eventadmin/test/TestPublisher.java
@@ -0,0 +1,713 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handler.eventadmin.test;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.Donut;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutConsumer;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.DonutProvider;
+import org.apache.felix.ipojo.handler.eventadmin.test.donut.EventTracker;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.event.Event;
+
+import java.util.*;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test the good behaviour of the EventAdminHandler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TestPublisher extends Common {
+
+    /**
+     * The number of providers to test.
+     */
+    private static final int NUMBER_OF_PROVIDERS = 6;
+    /**
+     * The number of providers using the event admin handler to test.
+     */
+    private static final int NUMBER_OF_EAH_PROVIDERS = 4;
+    /**
+     * The number of consumers to test.
+     */
+    private static final int NUMBER_OF_CONSUMERS = 6;
+    /**
+     * The number of synchronous providers to test.
+     */
+    private static final int NUMBER_OF_SYNCHRONOUS_PROVIDERS = 3;
+    /**
+     * The number of slow consumers to test.
+     */
+    private static final int NUMBER_OF_QUICK_CONSUMERS = 3;
+    /**
+     * The list of topics to test.
+     */
+    private static final String[] TOPICS_LIST = {"foo", "bar", "nut",
+            "foo,bar", "bar,nut", "foo,nut", "foo,bar,nut"};
+    /**
+     * The utility class instance.
+     */
+    public EahTestUtils m_utils;
+    /**
+     * The providers' instances.
+     */
+    private ComponentInstance[] m_providersInstances;
+    /**
+     * The providers' service references.
+     */
+    private ServiceReference[] m_providersServices;
+    /**
+     * The providers' services.
+     */
+    private DonutProvider[] m_providers;
+    /**
+     * The synchronous providers' services.
+     */
+    private DonutProvider[] m_synchronousProviders;
+    /**
+     * The instances of providers that uses the event admin handler.
+     */
+    private ComponentInstance[] m_eahProvidersInstances;
+    /**
+     * The services of the providers that uses the event admin handler.
+     */
+    private DonutProvider[] m_eahProviders;
+    /**
+     * The synchronous donut event provider service.
+     */
+    private DonutProvider m_synchronousDonutEventProvider;
+    /**
+     * The consumers' instances.
+     */
+    private ComponentInstance[] m_consumersInstances;
+    /**
+     * The consumers' service references.
+     */
+    private ServiceReference[] m_consumersServices;
+    /**
+     * The consumers' services.
+     */
+    private DonutConsumer[] m_consumers;
+    /**
+     * The slow consumers' services.
+     */
+    private DonutConsumer[] m_quickConsumers;
+    /**
+     * The event tracker' instances.
+     */
+    private ComponentInstance m_eventTrackerInstance;
+    /**
+     * The event tracker' service references.
+     */
+    private ServiceReference m_eventTrackerService;
+    /**
+     * The event tracker service.
+     */
+    private EventTracker m_eventTracker;
+    /**
+     * The filtered consumers' instances.
+     */
+    private ComponentInstance[] m_filteredConsumersInstances;
+    /**
+     * The filtered consumers' service references.
+     */
+    private ServiceReference[] m_filteredConsumersServices;
+    /**
+     * The filtered consumers' services.
+     */
+    private DonutConsumer[] m_filteredConsumers;
+    /**
+     * The providers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsProvidersInstances;
+    /**
+     * The providers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsProvidersServices;
+    /**
+     * The providers' service with specified topics.
+     */
+    private DonutProvider[] m_topicsProviders;
+    /**
+     * The provider that send donuts on the "foo" topic.
+     */
+    private DonutProvider m_fooProvider;
+    /**
+     * The provider that send donuts on the "bar" topic.
+     */
+    private DonutProvider m_barProvider;
+    /**
+     * The provider that send donuts on the "nut" topic.
+     */
+    private DonutProvider m_nutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar" topics.
+     */
+    private DonutProvider m_fooBarProvider;
+    /**
+     * The provider that send donuts on the "bar,nut" topics.
+     */
+    private DonutProvider m_barNutProvider;
+    /**
+     * The provider that send donuts on the "foo,nut" topics.
+     */
+    private DonutProvider m_fooNutProvider;
+    /**
+     * The provider that send donuts on the "foo,bar,nut" topics.
+     */
+    private DonutProvider m_fooBarNutProvider;
+    /**
+     * The consumers' instances with specified topics.
+     */
+    private ComponentInstance[] m_topicsConsumersInstances;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private ServiceReference[] m_topicsConsumersServices;
+    /**
+     * The consumers' service references with specified topics.
+     */
+    private DonutConsumer[] m_topicsConsumers;
+    /**
+     * The consumer that receive donuts on the "foo" topic.
+     */
+    private DonutConsumer m_fooConsumer;
+    /**
+     * The consumer that receive donuts on the "bar" topic.
+     */
+    private DonutConsumer m_barConsumer;
+    /**
+     * The consumer that receive donuts on the "nut" topic.
+     */
+    private DonutConsumer m_nutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar" topics.
+     */
+    private DonutConsumer m_fooBarConsumer;
+    /**
+     * The consumer that receive donuts on the "bar,nut" topics.
+     */
+    private DonutConsumer m_barNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,nut" topics.
+     */
+    private DonutConsumer m_fooNutConsumer;
+    /**
+     * The consumer that receive donuts on the "foo,bar,nut" topics.
+     */
+    private DonutConsumer m_fooBarNutConsumer;
+
+    /**
+     * Initialization before test cases.
+     * <p/>
+     * Create all the instances
+     *
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened
+     */
+    @Before
+    public void setUp()
+            throws UnacceptableConfiguration, MissingHandlerException,
+            ConfigurationException {
+
+        m_utils = new EahTestUtils(bc, ipojoHelper);
+        Dictionary properties = new Hashtable();
+
+        // All the providers
+        m_providersInstances = new ComponentInstance[NUMBER_OF_PROVIDERS];
+        m_providersServices = new ServiceReference[NUMBER_OF_PROVIDERS];
+        m_providers = new DonutProvider[NUMBER_OF_PROVIDERS];
+        m_synchronousProviders = new DonutProvider[NUMBER_OF_SYNCHRONOUS_PROVIDERS];
+        m_eahProviders = new DonutProvider[NUMBER_OF_EAH_PROVIDERS];
+        m_eahProvidersInstances = new ComponentInstance[NUMBER_OF_EAH_PROVIDERS];
+        m_topicsProvidersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsProvidersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsProviders = new DonutProvider[TOPICS_LIST.length];
+
+        // Create the (asynchronous) donut provider
+        properties.put("instance.name", "asynchronous donut provider");
+        m_providersInstances[0] = m_utils.getDonutProviderUsingPublishesFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut provider");
+        m_providersInstances[1] = m_utils.getSynchronousDonutProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous donut event provider");
+        m_providersInstances[2] = m_utils.getDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous donut event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous donut event provider");
+        m_providersInstances[3] = m_utils
+                .getSynchronousDonutEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the (asynchronous) event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "asynchronous event provider");
+        m_providersInstances[4] = m_utils.getEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Create the synchronous event provider
+        properties = new Hashtable();
+        properties.put("instance.name", "synchronous event provider");
+        m_providersInstances[5] = m_utils.getSynchronousEventProviderFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            m_providersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutProvider.class.getName(),
+                    m_providersInstances[i].getInstanceName());
+            m_providers[i] = (DonutProvider) bc
+                    .getService(m_providersServices[i]);
+        }
+        m_synchronousProviders[0] = m_providers[1];
+        m_synchronousProviders[1] = m_providers[3];
+        m_synchronousProviders[2] = m_providers[5];
+        m_eahProviders[0] = m_providers[0];
+        m_eahProviders[1] = m_providers[1];
+        m_eahProviders[2] = m_providers[2];
+        m_eahProviders[3] = m_providers[3];
+        m_eahProvidersInstances[0] = m_providersInstances[0];
+        m_eahProvidersInstances[1] = m_providersInstances[1];
+        m_eahProvidersInstances[2] = m_providersInstances[2];
+        m_eahProvidersInstances[3] = m_providersInstances[3];
+        m_synchronousDonutEventProvider = m_providers[3];
+
+        // All the consumers
+        m_consumersInstances = new ComponentInstance[NUMBER_OF_CONSUMERS];
+        m_consumersServices = new ServiceReference[NUMBER_OF_CONSUMERS];
+        m_consumers = new DonutConsumer[NUMBER_OF_CONSUMERS];
+        m_quickConsumers = new DonutConsumer[NUMBER_OF_QUICK_CONSUMERS];
+        m_filteredConsumersInstances = new ComponentInstance[Donut.FLAVOURS.length];
+        m_filteredConsumersServices = new ServiceReference[Donut.FLAVOURS.length];
+        m_filteredConsumers = new DonutConsumer[Donut.FLAVOURS.length];
+        m_topicsConsumersInstances = new ComponentInstance[TOPICS_LIST.length];
+        m_topicsConsumersServices = new ServiceReference[TOPICS_LIST.length];
+        m_topicsConsumers = new DonutConsumer[TOPICS_LIST.length];
+
+        // Create the (quick) donut consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut consumer");
+        m_consumersInstances[0] = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick donut event consumer");
+        m_consumersInstances[1] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the (quick) event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "quick event consumer");
+        m_consumersInstances[2] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut consumer
+        properties = new Hashtable();
+        properties.put("slow", Boolean.TRUE);
+        properties.put("instance.name", "slow donut consumer");
+        m_consumersInstances[3] = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow donut event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow donut event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[4] = m_utils.getDonutEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Create the slow event consumer
+        properties = new Hashtable();
+        properties.put("instance.name", "slow event consumer");
+        properties.put("slow", Boolean.TRUE);
+        m_consumersInstances[5] = m_utils.getEventConsumerFactory()
+                .createComponentInstance(properties);
+
+        // Get all the services references
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumersServices[i] = ipojoHelper.getServiceReferenceByName(
+                    DonutConsumer.class.getName(),
+                    m_consumersInstances[i].getInstanceName());
+            m_consumers[i] = (DonutConsumer) bc
+                    .getService(m_consumersServices[i]);
+        }
+        m_quickConsumers[0] = m_consumers[0];
+        m_quickConsumers[1] = m_consumers[1];
+        m_quickConsumers[2] = m_consumers[2];
+
+        // Create the event tracker
+        properties = new Hashtable();
+        properties.put("instance.name", "event tracker");
+        m_eventTrackerInstance = m_utils.getEventTrackerFactory()
+                .createComponentInstance(properties);
+        m_eventTrackerService = ipojoHelper.getServiceReferenceByName(
+                EventTracker.class.getName(), m_eventTrackerInstance
+                .getInstanceName());
+        m_eventTracker = (EventTracker) bc
+                .getService(m_eventTrackerService);
+
+        // Create the filtered consumer
+        Dictionary filter = new Hashtable();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            String flavour = Donut.FLAVOURS[i];
+            properties = new Hashtable();
+            filter.put("donut-event-subscriber", "(flavour=" + flavour + ")");
+            properties.put("instance.name", flavour + " donut consumer");
+            properties.put("event.filter", filter);
+            m_filteredConsumersInstances[i] = m_utils
+                    .getDonutEventConsumerFactory().createComponentInstance(
+                            properties);
+            m_filteredConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutConsumer.class
+                            .getName(), m_filteredConsumersInstances[i]
+                            .getInstanceName());
+            m_filteredConsumers[i] = (DonutConsumer) bc
+                    .getService(m_filteredConsumersServices[i]);
+        }
+
+        // Create the providers and consumers selling and receiving donuts on
+        // specific topics
+        Dictionary topics = new Hashtable();
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            String topicsString = TOPICS_LIST[i];
+            properties = new Hashtable();
+            // Create provider
+            topics.put("donut-publisher", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut provider");
+            m_topicsProvidersInstances[i] = m_utils
+                    .getSynchronousDonutProviderFactory()
+                    .createComponentInstance(properties);
+            m_topicsProvidersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutProvider.class
+                            .getName(), m_topicsProvidersInstances[i]
+                            .getInstanceName());
+            m_topicsProviders[i] = (DonutProvider) bc
+                    .getService(m_topicsProvidersServices[i]);
+
+            // Create consumer
+            properties = new Hashtable();
+            topics.put("donut-subscriber", topicsString);
+            properties.put("event.topics", topics);
+            properties.put("instance.name", topicsString + " donut consumer");
+
+            m_topicsConsumersInstances[i] = m_utils.getDonutConsumerFactory()
+                    .createComponentInstance(properties);
+            m_topicsConsumersServices[i] = ipojoHelper
+                    .getServiceReferenceByName(DonutConsumer.class
+                            .getName(), m_topicsConsumersInstances[i]
+                            .getInstanceName());
+            m_topicsConsumers[i] = (DonutConsumer) bc
+                    .getService(m_topicsConsumersServices[i]);
+            topics.remove("donut-subscriber");
+        }
+
+        m_fooProvider = m_topicsProviders[0];
+        m_barProvider = m_topicsProviders[1];
+        m_nutProvider = m_topicsProviders[2];
+        m_fooBarProvider = m_topicsProviders[3];
+        m_barNutProvider = m_topicsProviders[4];
+        m_fooNutProvider = m_topicsProviders[5];
+        m_fooBarNutProvider = m_topicsProviders[6];
+        m_fooConsumer = m_topicsConsumers[0];
+        m_barConsumer = m_topicsConsumers[1];
+        m_nutConsumer = m_topicsConsumers[2];
+        m_fooBarConsumer = m_topicsConsumers[3];
+        m_barNutConsumer = m_topicsConsumers[4];
+        m_fooNutConsumer = m_topicsConsumers[5];
+        m_fooBarNutConsumer = m_topicsConsumers[6];
+
+    }
+
+    /**
+     * Creates a subscriber listening on a pattern topic (ending with '*').
+     *
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.MissingHandlerException
+     *          something bad happened.
+     * @throws org.apache.felix.ipojo.UnacceptableConfiguration
+     *          something bad happened.
+     */
+    @Test
+    public void testSubscriberWithPatternTopic() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        Dictionary properties = new Hashtable();
+        Dictionary topics = new Hashtable();
+
+        // Create the donut consumer instance, listening on a pattern topic
+        properties.put("instance.name", "subscriber with pattern topic");
+        topics.put("donut-subscriber", "a/pattern/topic/*");
+        properties.put("event.topics", topics);
+
+        ComponentInstance instance = m_utils.getDonutConsumerFactory()
+                .createComponentInstance(properties);
+        instance.dispose();
+    }
+
+    /**
+     * Test the event handler reliability by sending events with all kinds of
+     * publisher and check they are received by all kinds of subscriber.
+     */
+    @Test
+    public void testReliability() {
+
+        // Flush donut list for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            m_consumers[i].clearDonuts();
+        }
+
+        // Send a lot of donut with each provider
+        List sentDonuts = new ArrayList(NUMBER_OF_PROVIDERS
+                * EahTestUtils.NUMBER_OF_TESTS);
+        for (int i = 0; i < NUMBER_OF_PROVIDERS; i++) {
+            for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+                sentDonuts.add(m_providers[i].sellDonut());
+            }
+        }
+
+        // Wait a respectable amount of time
+        EahTestUtils.sleep(EahTestUtils.BLACK_LIST_TIME
+                + EahTestUtils.A_LONG_TIME);
+
+        // Collect all received donuts for each consumer
+        for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
+            List receivedDonuts = Arrays.asList(m_consumers[i].getAllDonuts());
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts.",
+                    sentDonuts.size(), receivedDonuts.size());
+            assertTrue("The receiver must have eaten all sent donuts.",
+                    receivedDonuts.containsAll(sentDonuts));
+        }
+    }
+
+    /**
+     * Test the synchronism of event sending for the component.
+     * <p/>
+     * This test consists to send synchronously a big amount of donuts and to
+     * check immediately if it has been received (by all quick consumers).
+     */
+    @Test
+    public void testSynchronism() {
+
+        // Flush donut list for quick consumers
+        for (int i = 0; i < NUMBER_OF_QUICK_CONSUMERS; i++) {
+            m_quickConsumers[i].clearDonuts();
+        }
+
+        // Send a lot of donuts and check they are immediately received.
+        Donut sentDonut;
+        Donut receivedDonut;
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            for (int j = 0; j < NUMBER_OF_SYNCHRONOUS_PROVIDERS; j++) {
+                sentDonut = m_synchronousProviders[j].sellDonut();
+                for (int k = 0; k < NUMBER_OF_QUICK_CONSUMERS; k++) {
+                    receivedDonut = m_quickConsumers[k].getDonut();
+                    assertEquals(
+                            "The donut must have been received immediately and be the be the same as the sent one.",
+                            sentDonut, receivedDonut);
+                }
+            }
+        }
+    }
+
+    /**
+     * Test that the received events contains the instance name of the sender.
+     */
+    @Test
+    public void testInstanceName() {
+
+        // Flush event list of the event tracker
+        m_eventTracker.clearEvents();
+
+        // Send donuts and check the sender instance name
+        Event receivedEvent;
+        for (int i = 0; i < NUMBER_OF_EAH_PROVIDERS; i++) {
+            m_eahProviders[i].sellDonut();
+            receivedEvent = m_eventTracker.waitForEvent();
+            assertEquals(
+                    "The instance name property of the received message must be the same as the sender instance name.",
+                    m_eahProvidersInstances[i].getInstanceName(), receivedEvent
+                    .getProperty("publisher.instance.name"));
+        }
+    }
+
+    /**
+     * Test the event filtering.
+     * <p/>
+     * This test send donuts with different flavours. Each filtered consumer
+     * must receive only a certain kind of donut. Of course, all donuts must
+     * have been received too.
+     */
+    @Test
+    public void testFilters() {
+
+        // The sent donuts, sorted by flavour
+        List[] sentDonuts = new List[Donut.FLAVOURS.length];
+
+        // Flush donut list for each filtered consumer
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            m_filteredConsumers[i].clearDonuts();
+            sentDonuts[i] = new ArrayList(EahTestUtils.NUMBER_OF_TESTS
+                    / Donut.FLAVOURS.length);
+        }
+
+        // Send donuts
+        for (int j = 0; j < EahTestUtils.NUMBER_OF_TESTS; j++) {
+            Donut donut = m_synchronousDonutEventProvider.sellDonut();
+            sentDonuts[EahTestUtils.flavourIndex(donut.getFlavour())]
+                    .add(donut);
+        }
+
+        // Check the received donuts
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            Donut[] receivedDonuts = m_filteredConsumers[i].getAllDonuts();
+            assertEquals(
+                    "The number of received donuts must be the same as the number of sent donuts with the matching flavour.",
+                    sentDonuts[i].size(), receivedDonuts.length);
+            assertTrue(
+                    "The receiver must have eaten all sent donuts matching the wanted flavour.",
+                    Arrays.asList(receivedDonuts).containsAll(sentDonuts[i]));
+        }
+
+    }
+
+    /**
+     * Test the event topic.
+     * <p/>
+     * This test send donuts on several topics. Each consumer (who listens to
+     * one or several topics) must receive donuts sent on his specifics topics.
+     */
+    @Test
+    public void testTopics() {
+
+        // The sent donuts, sorted by topic
+        int foos = 0;
+        int bars = 0;
+        int nuts = 0;
+
+        // Flush consumers
+        m_fooConsumer.clearDonuts();
+        m_barConsumer.clearDonuts();
+        m_nutConsumer.clearDonuts();
+        m_fooBarConsumer.clearDonuts();
+        m_barNutConsumer.clearDonuts();
+        m_fooNutConsumer.clearDonuts();
+        m_fooBarNutConsumer.clearDonuts();
+
+        // Send donuts
+        for (int i = 0; i < EahTestUtils.NUMBER_OF_TESTS; i++) {
+            m_fooProvider.sellDonut();
+            foos++;
+
+            m_barProvider.sellDonut();
+            bars++;
+
+            m_nutProvider.sellDonut();
+            nuts++;
+
+            m_fooBarProvider.sellDonut();
+            foos++;
+            bars++;
+
+            m_barNutProvider.sellDonut();
+            bars++;
+            nuts++;
+
+            m_fooNutProvider.sellDonut();
+            foos++;
+            nuts++;
+
+            m_fooBarNutProvider.sellDonut();
+            foos++;
+            bars++;
+            nuts++;
+        }
+
+        // Check received donuts
+        assertEquals("The number of received donuts must be correct.", foos,
+                m_fooConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars,
+                m_barConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", nuts,
+                m_nutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars, m_fooBarConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", bars
+                + nuts, m_barNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + nuts, m_fooNutConsumer.getAllDonuts().length);
+        assertEquals("The number of received donuts must be correct.", foos
+                + bars + nuts, m_fooBarNutConsumer.getAllDonuts().length);
+
+    }
+
+    /**
+     * Finalization after test cases.
+     * <p/>
+     * Release all services references and destroy instances.
+     */
+    @After
+    public void tearDown() {
+        int index;
+        for (index = 0; index < NUMBER_OF_PROVIDERS; index++) {
+            bc.ungetService(m_providersServices[index]);
+            m_providersInstances[index].dispose();
+        }
+        for (index = 0; index < NUMBER_OF_CONSUMERS; index++) {
+            bc.ungetService(m_consumersServices[index]);
+            m_consumersInstances[index].dispose();
+        }
+        bc.ungetService(m_eventTrackerService);
+        m_eventTrackerInstance.dispose();
+        for (int i = 0; i < Donut.FLAVOURS.length; i++) {
+            bc.ungetService(m_filteredConsumersServices[i]);
+            m_filteredConsumersInstances[i].dispose();
+        }
+        for (int i = 0; i < TOPICS_LIST.length; i++) {
+            bc.ungetService(m_topicsProvidersServices[i]);
+            m_topicsProvidersInstances[i].dispose();
+            bc.ungetService(m_topicsConsumersServices[i]);
+            m_topicsConsumersInstances[i].dispose();
+        }
+
+    }
+
+}
diff --git a/ipojo/handler/eventadmin/eventadmin-handler/DEPENDENCIES b/ipojo/handler/eventadmin/eventadmin-handler/DEPENDENCIES
new file mode 100644
index 0000000..b92f2f0
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler/DEPENDENCIES
@@ -0,0 +1,18 @@
+Apache Felix iPOJO Event Admin Handler
+Copyright 2008-2011 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0.
+
+III. Overall License Summary
+- Apache License 2.0
diff --git a/ipojo/handler/eventadmin/eventadmin-handler/LICENSE b/ipojo/handler/eventadmin/eventadmin-handler/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/ipojo/handler/eventadmin/eventadmin-handler/NOTICE b/ipojo/handler/eventadmin/eventadmin-handler/NOTICE
new file mode 100644
index 0000000..253c41f
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler/NOTICE
@@ -0,0 +1,6 @@
+Apache Felix iPOJO Event Admin Handler
+Copyright 2008-2011 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
diff --git a/ipojo/handler/eventadmin/doc/changelog.txt b/ipojo/handler/eventadmin/eventadmin-handler/doc/changelog.txt
similarity index 100%
rename from ipojo/handler/eventadmin/doc/changelog.txt
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/changelog.txt
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers.html b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers.html
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers.html
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers.html
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/apache.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/apache.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/apache.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/apache.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/button.html b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/button.html
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/button.html
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/button.html
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/button_data/2009-europe-125x125.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/button_data/2009-europe-125x125.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/button_data/2009-europe-125x125.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/button_data/2009-europe-125x125.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/feed-icon-32x32.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/feed-icon-32x32.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/feed-icon-32x32.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/feed-icon-32x32.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/footer.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/footer.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/footer.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/footer.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/ga.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/ga.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/ga.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/ga.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/handler-arch.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/handler-arch.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/handler-arch.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/handler-arch.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/header.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/header.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/header.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/header.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/hoverIntent.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/hoverIntent.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/hoverIntent.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/hoverIntent.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/information.gif b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/information.gif
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/information.gif
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/information.gif
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/ipojo.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/ipojo.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/ipojo.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/ipojo.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/jquery-1.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/jquery-1.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/jquery-1.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/jquery-1.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/linkext7.gif b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/linkext7.gif
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/linkext7.gif
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/linkext7.gif
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/logo.png b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/logo.png
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/logo.png
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/logo.png
Binary files differ
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushCSharp.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushCSharp.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushCSharp.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushCSharp.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushDelphi.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushDelphi.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushDelphi.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushDelphi.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushJScript.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushJScript.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushJScript.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushJScript.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushJava.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushJava.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushJava.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushJava.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushPhp.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushPhp.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushPhp.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushPhp.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushPython.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushPython.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushPython.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushPython.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushShell.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushShell.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushShell.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushShell.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushSql.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushSql.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushSql.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushSql.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushVb.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushVb.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushVb.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushVb.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushXml.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushXml.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shBrushXml.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shBrushXml.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/shCore.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shCore.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/shCore.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/shCore.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/site.css b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/site.css
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/site.css
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/site.css
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/superfish.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/superfish.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/superfish.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/superfish.js
diff --git a/ipojo/handler/eventadmin/doc/event-admin-handlers_files/supersubs.js b/ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/supersubs.js
similarity index 100%
rename from ipojo/handler/eventadmin/doc/event-admin-handlers_files/supersubs.js
rename to ipojo/handler/eventadmin/eventadmin-handler/doc/event-admin-handlers_files/supersubs.js
diff --git a/ipojo/handler/eventadmin/metadata.xml b/ipojo/handler/eventadmin/eventadmin-handler/metadata.xml
similarity index 100%
rename from ipojo/handler/eventadmin/metadata.xml
rename to ipojo/handler/eventadmin/eventadmin-handler/metadata.xml
diff --git a/ipojo/handler/eventadmin/obr.xml b/ipojo/handler/eventadmin/eventadmin-handler/obr.xml
similarity index 100%
rename from ipojo/handler/eventadmin/obr.xml
rename to ipojo/handler/eventadmin/eventadmin-handler/obr.xml
diff --git a/ipojo/handler/eventadmin/eventadmin-handler/pom.xml b/ipojo/handler/eventadmin/eventadmin-handler/pom.xml
new file mode 100644
index 0000000..856fa2c
--- /dev/null
+++ b/ipojo/handler/eventadmin/eventadmin-handler/pom.xml
@@ -0,0 +1,240 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>felix-parent</artifactId>
+        <version>1.2.1</version>
+        <relativePath>../../../../pom/pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>bundle</packaging>
+    <name>Apache Felix iPOJO Event Admin Handler</name>
+    <artifactId>org.apache.felix.ipojo.handler.eventadmin</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+
+    <description>
+        iPOJO extension to easily interact with the OSGi Event Admin.
+    </description>
+    <url>http://felix.apache.org/site/event-admin-handlers.html</url>
+
+    <properties>
+        <exam.version>3.0.0</exam.version>
+        <url.version>1.5.1</url.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.ipojo</artifactId>
+            <version>1.6.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>1.4.3</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>org.apache.felix.ipojo.handlers.event*;version="1.2.0"</Export-Package>
+                        <Bundle-Name>${project.name}</Bundle-Name>
+                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+                        <Bundle-Description>iPOJO Event Admin Handlers
+                        </Bundle-Description>
+                        <Bundle-DocURL>
+                            http://felix.apache.org/site/event-admin-handlers.html
+                        </Bundle-DocURL>
+                        <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
+                        <Include-Resource>
+                            META-INF/LICENSE=LICENSE,
+                            META-INF/NOTICE=NOTICE,
+                            META-INF/DEPENDENCIES=DEPENDENCIES
+                        </Include-Resource>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-ipojo-plugin</artifactId>
+                <version>1.9.0-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>ipojo-bundle</goal>
+                        </goals>
+                        <configuration>
+                            <metadata>metadata.xml</metadata>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>rat-maven-plugin</artifactId>
+                <configuration>
+                    <excludeSubProjects>false</excludeSubProjects>
+                    <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
+                    <useMavenDefaultExcludes>true</useMavenDefaultExcludes>
+                    <excludes>
+                        <param>doc/**/*</param>
+                        <param>maven-eclipse.xml</param>
+                        <param>.checkstyle</param>
+                        <param>.externalToolBuilders/*</param>
+                        <param>LICENSE.asm</param>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <configuration>
+                    <enableRulesSummary>false</enableRulesSummary>
+                    <violationSeverity>warning</violationSeverity>
+                    <configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.5.1</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>test</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-invoker-plugin</artifactId>
+                        <version>1.8</version>
+                        <configuration>
+                            <streamLogs>true</streamLogs>
+                            <goals>
+                                <goal>clean</goal>
+                                <goal>test</goal>
+                            </goals>
+                            <cloneClean>true</cloneClean>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>regular</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>felix</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/regular</cloneProjectsTo>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>test-all</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-invoker-plugin</artifactId>
+                        <version>1.8</version>
+                        <configuration>
+                            <streamLogs>true</streamLogs>
+                            <goals>
+                                <goal>clean</goal>
+                                <goal>test</goal>
+                            </goals>
+                            <cloneClean>true</cloneClean>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>equinox-native</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>equinox</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/equinox-native</cloneProjectsTo>
+
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>felix-native</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>felix</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/felix-native</cloneProjectsTo>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>knopflerfish-native</id>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <profiles>
+                                        <profile>knopflerfish</profile>
+                                    </profiles>
+                                    <cloneProjectsTo>${project.build.directory}/knopflerfish-native</cloneProjectsTo>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandler.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandler.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandler.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandler.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java
diff --git a/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java b/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
diff --git a/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd b/ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd
similarity index 100%
rename from ipojo/handler/eventadmin/src/main/resources/event-admin.xsd
rename to ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd
diff --git a/ipojo/handler/eventadmin/pom.xml b/ipojo/handler/eventadmin/pom.xml
index 76bd5f9..846d2e2 100644
--- a/ipojo/handler/eventadmin/pom.xml
+++ b/ipojo/handler/eventadmin/pom.xml
@@ -16,107 +16,112 @@
   specific language governing permissions and limitations
   under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <parent>
-    <groupId>org.apache.felix</groupId>
-    <artifactId>felix-parent</artifactId>
-    <version>1.2.1</version>
-    <relativePath>../../pom/pom.xml</relativePath>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <packaging>bundle</packaging>
-  <name>Apache Felix iPOJO Event Admin Handler</name>
-  <artifactId>org.apache.felix.ipojo.handler.eventadmin</artifactId>
-  <version>1.9.0-SNAPSHOT</version>
-  
-  <description>
-  iPOJO extension to easily interact with the OSGi Event Admin.
-  </description>
-  <url>http://felix.apache.org/site/event-admin-handlers.html</url>
-  
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.ipojo</artifactId>
-      <version>1.6.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <version>4.0.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <version>4.0.0</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
         <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.3</version>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Export-Package>org.apache.felix.ipojo.handlers.event*;version="1.2.0"</Export-Package>
-            <Bundle-Name>${project.name}</Bundle-Name>
-            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
-            <Bundle-Description> iPOJO Event Admin Handlers
-            </Bundle-Description>
-            <Bundle-DocURL>
-             http://felix.apache.org/site/event-admin-handlers.html
-            </Bundle-DocURL>
-            <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
-            <Include-Resource> 
-              META-INF/LICENSE=LICENSE,
-              META-INF/NOTICE=NOTICE,
-              META-INF/DEPENDENCIES=DEPENDENCIES 
-            </Include-Resource>
-          </instructions>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-ipojo-plugin</artifactId>
-        <version>1.9.0-SNAPSHOT</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>ipojo-bundle</goal>
-            </goals>
-            <configuration>
-              <metadata>metadata.xml</metadata>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>rat-maven-plugin</artifactId>
-        <configuration>
-          <excludeSubProjects>false</excludeSubProjects>
-          <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
-          <useMavenDefaultExcludes>true</useMavenDefaultExcludes>
-          <excludes>
-            <param>doc/**/*</param>
-            <param>maven-eclipse.xml</param>
-            <param>.checkstyle</param>
-            <param>.externalToolBuilders/*</param>
-            <param>LICENSE.asm</param>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-        <configuration>
-          <enableRulesSummary>false</enableRulesSummary>
-          <violationSeverity>warning</violationSeverity>
-          <configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+        <artifactId>felix-parent</artifactId>
+        <version>1.2.1</version>
+        <relativePath>../../pom/pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.felix.ipojo.handler.event-admin-handler-project</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <name>Apache Felix iPOJO Event Admin Handler Project</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>eventadmin-handler</module>
+        <module>eventadmin-handler-it</module>
+    </modules>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>.</directory>
+                <targetPath>META-INF</targetPath>
+                <includes>
+                    <include>LICENSE*</include>
+                    <include>NOTICE*</include>
+                    <include>DEPENDENCIES*</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>test</id>
+            <modules>
+                <module>core-it</module>
+            </modules>    
+        </profile>
+        <profile>
+            <id>test-all</id>
+            <modules>
+                <module>core-it</module>
+            </modules>    
+        </profile>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>make-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptorRefs>
+                                        <descriptorRef>project</descriptorRef>
+                                    </descriptorRefs>
+                                    <!-- we don't want to attach all the assemblies, such as bz2 -->
+                                    <attach>false</attach>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <!-- only attach the project and bin assemblies, in tar.gz and zip flavors -->
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-assemblies</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>attach-artifact</goal>
+                                </goals>
+                                <configuration>
+                                    <artifacts>
+                                        <artifact>
+                                            <file>
+                                                ${project.build.directory}/${project.artifactId}-${project.version}-project.tar.gz
+                                            </file>
+                                            <classifier>project</classifier>
+                                            <type>tar.gz</type>
+                                        </artifact>
+                                        <artifact>
+                                            <file>
+                                                ${project.build.directory}/${project.artifactId}-${project.version}-project.zip
+                                            </file>
+                                            <classifier>project</classifier>
+                                            <type>zip</type>
+                                        </artifact>
+                                    </artifacts>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>