Forgot a file during the last commit.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1495741 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core-it/ipojo-api-test/pom.xml b/ipojo/runtime/core-it/ipojo-api-test/pom.xml
new file mode 100644
index 0000000..457f4c5
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.ipojo.runtime.core-it</artifactId>
+        <version>1.10.2-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ipojo-api-test</artifactId>
+
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.ipojo.composite</artifactId>
+            <version>1.10.2-SNAPSHOT</version>
+            <exclusions>
+                <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.ipojo.api</artifactId>
+            <version>1.10.2-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.felix</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.ipojo.handler.whiteboard</artifactId>
+            <version>1.4.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>org.osgi.core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>org.apache.felix.ipojo</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+    
+</project>
\ No newline at end of file
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/FooImpl.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/FooImpl.java
new file mode 100644
index 0000000..8e396d6
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/FooImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api.components;
+
+import org.apache.felix.ipojo.runtime.core.api.services.Foo;
+
+public class FooImpl implements Foo {
+    
+   // private List<String> m_list = new ArrayList<String>();
+
+    public void doSomething() {
+       // Do something...
+        System.out.println("Hello World !");
+    }
+    
+    public FooImpl(String s) {
+        _setIM(s);
+    }
+    
+    public void _setIM(String s) {
+        
+    }
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/HostImpl.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/HostImpl.java
new file mode 100644
index 0000000..ab75f87
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/HostImpl.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api.components;
+
+import org.osgi.framework.ServiceReference;
+
+public class HostImpl {
+    
+    public void arrival(ServiceReference ref) {
+        
+    }
+    
+    public void departure(ServiceReference ref) {
+        
+    }
+    
+    public void modification(ServiceReference ref) {
+        
+    }
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyComponentImpl.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyComponentImpl.java
new file mode 100644
index 0000000..a07feb8
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyComponentImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.runtime.core.api.services.Foo;
+
+/**
+ * This class is marked as a component to be manipulated.
+ */
+@Component(name="do-not-use-this-factory", public_factory = false)
+public class MyComponentImpl {
+    
+    private Foo myFoo;
+    
+    private int anInt;
+    
+    public MyComponentImpl() {
+        anInt = 2;
+    }
+    
+    public MyComponentImpl(int i) {
+        anInt = i;
+    }
+
+    public void start() {
+       myFoo.doSomething();
+       if (anInt > 0) {
+           System.out.println("Set int to " + anInt);
+       }
+    }
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyServiceImpl.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyServiceImpl.java
new file mode 100644
index 0000000..7973ed7
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/components/MyServiceImpl.java
@@ -0,0 +1,28 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.felix.ipojo.runtime.core.api.components;

+

+import org.apache.felix.ipojo.runtime.core.api.services.MyService;

+

+public class MyServiceImpl implements MyService {

+    public double compute(double value) {

+	return Math.exp(value * Math.cosh(value));

+    }

+}

diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/BarService.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/BarService.java
new file mode 100644
index 0000000..faa9f38
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/BarService.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api.services;
+
+public interface BarService {
+    
+    public void doSomethingWithBar();
+    
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/Foo.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/Foo.java
new file mode 100644
index 0000000..719b2fd
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/Foo.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api.services;
+
+public interface Foo {
+    
+    
+    public void doSomething();
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/MyService.java b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/MyService.java
new file mode 100644
index 0000000..ed24f45
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/main/java/org/apache/felix/ipojo/runtime/core/api/services/MyService.java
@@ -0,0 +1,24 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.felix.ipojo.runtime.core.api.services;

+

+public interface MyService {

+    double compute(double value);

+}

diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Common.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Common.java
new file mode 100644
index 0000000..df7c115
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Common.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.composite.CompositeManager;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.ow2.chameleon.testing.helpers.BaseTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+
+/**
+ * Bootstrap the test from this project
+ */
+@ExamReactorStrategy(PerMethod.class)
+public class Common extends BaseTest {
+
+    public static ServiceContext getServiceContext(ComponentInstance ci) {
+        if (ci instanceof CompositeManager) {
+            return ((CompositeManager) ci).getServiceContext();
+        } else {
+            throw new RuntimeException("Cannot get the service context from a non composite instance");
+        }
+    }
+
+    @Override
+    public boolean deployiPOJOComposite() {
+        return true;
+    }
+
+    @Override
+    public boolean deployConfigAdmin() {
+        return true;
+    }
+
+    @Override
+    protected Option[] getCustomOptions() {
+        return new Option[]{
+                mavenBundle("org.apache.felix", "org.apache.felix.ipojo.handler.whiteboard").versionAsInProject(),
+                mavenBundle("org.apache.felix", "org.apache.felix.ipojo.api").versionAsInProject()
+        };
+    }
+
+    @Override
+    protected List<String> getExtraExports() {
+        return Arrays.asList(
+                "org.apache.felix.ipojo.runtime.core.api.components"
+        );
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/CompositeTest.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/CompositeTest.java
new file mode 100644
index 0000000..5d1c460
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/CompositeTest.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+import org.apache.felix.ipojo.*;
+import org.apache.felix.ipojo.api.Dependency;
+import org.apache.felix.ipojo.api.PrimitiveComponentType;
+import org.apache.felix.ipojo.api.Service;
+import org.apache.felix.ipojo.api.composite.*;
+import org.apache.felix.ipojo.runtime.core.api.components.FooImpl;
+import org.apache.felix.ipojo.runtime.core.api.components.MyComponentImpl;
+import org.apache.felix.ipojo.runtime.core.api.services.Foo;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+
+public class CompositeTest extends Common {
+
+    private BundleContext context;
+
+    @Before
+    public void setUp() {
+        context = getContext();
+    }
+
+    @Test
+    public void createACompositeWithcontainedInstance() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        PrimitiveComponentType cons = createAConsumer();
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("comp1")
+                .addInstance(new Instance(prov.getFactory().getName()))
+                .addInstance(new Instance(cons.getFactory().getName()));
+
+        ComponentInstance ci = type.createInstance();
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+
+        // Stop cons
+        cons.stop();
+        assertThat("ci is invalid", ci.getState(), is(ComponentInstance.INVALID));
+
+        // Restart cons
+        cons.start();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createACompositeWithAnInstantiatedService() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        prov.start();
+        PrimitiveComponentType cons = createAConsumer();
+
+        ServiceReference[] refs = osgiHelper.getServiceReferences(Factory.class.getName(),
+                "(component.providedServiceSpecifications=" + Foo.class.getName() + ")");
+        assertThat(refs.length, is(not(0)));
+
+        Factory factory = (Factory) osgiHelper.getServiceObject(refs[0]);
+        System.out.println(factory.getComponentDescription().getDescription());
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("comp2")
+                .addSubService(new InstantiatedService().setSpecification(Foo.class.getName()))
+                .addInstance(new Instance(cons.getFactory().getName()));
+
+        ComponentInstance ci = type.createInstance();
+
+        System.out.println(ci.getInstanceDescription().getDescription());
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+
+        // Stop prov
+        prov.stop();
+        assertThat("ci is invalid", ci.getState(), is(ComponentInstance.INVALID));
+
+        // Restart prov
+        prov.start();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createACompositeWithAnOptionalInstantiatedService() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        prov.start();
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("comp3")
+                .addSubService(new InstantiatedService().setSpecification(Foo.class.getName()).setOptional(true));
+
+        ComponentInstance ci = type.createInstance();
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+
+        // Stop prov
+        prov.stop();
+        assertThat("ci is valid - 1", ci.getState(), is(ComponentInstance.VALID));
+
+        // Restart prov
+        prov.start();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createACompositeWithAnImportedService() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        prov.createInstance();
+        PrimitiveComponentType cons = createAConsumer();
+
+        ServiceReference[] refs = osgiHelper.getServiceReferences(Factory.class.getName(),
+                "(component.providedServiceSpecifications=" + Foo.class.getName() + ")");
+        assertThat(refs.length, is(not(0)));
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("comp2")
+                .addSubService(new ImportedService().setSpecification(Foo.class.getName()))
+                .addInstance(new Instance(cons.getFactory().getName()));
+
+        ComponentInstance ci = type.createInstance();
+
+        System.out.println(ci.getInstanceDescription().getDescription());
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+
+        // Stop prov
+        prov.stop();
+        assertThat("ci is invalid", ci.getState(), is(ComponentInstance.INVALID));
+
+        // Restart prov
+        prov.start();
+        prov.createInstance();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createACompositeWithAnOptionalImportedService() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        prov.createInstance();
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("comp3")
+                .addSubService(new ImportedService().setSpecification(Foo.class.getName()).setOptional(true));
+
+        ComponentInstance ci = type.createInstance();
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+
+        // Stop prov
+        prov.stop();
+        assertThat("ci is valid - 1", ci.getState(), is(ComponentInstance.VALID));
+
+        // Restart prov
+        prov.start();
+        prov.createInstance();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createACompositeWithExportingAService() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Define the component types
+        PrimitiveComponentType prov = createAProvider();
+        prov.start();
+        PrimitiveComponentType cons = createAConsumer();
+        ComponentInstance c = cons.createInstance();
+
+        CompositeComponentType type = new CompositeComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("compExport")
+                .addSubService(new InstantiatedService().setSpecification(Foo.class.getName()))
+                .addService(new ExportedService().setSpecification(Foo.class.getName()));
+
+        ComponentInstance ci = type.createInstance();
+
+        assertThat("ci is valid", ci.getState(), is(ComponentInstance.VALID));
+        assertThat("c is valid", c.getState(), is(ComponentInstance.VALID));
+
+
+        // Stop prov
+        prov.stop();
+        assertThat("ci is invalid", ci.getState(), is(ComponentInstance.INVALID));
+        assertThat("c is invalid", c.getState(), is(ComponentInstance.INVALID));
+
+
+        // Restart prov
+        prov.start();
+        assertThat("ci is valid - 2", ci.getState(), is(ComponentInstance.VALID));
+        assertThat("c is valid - 2", c.getState(), is(ComponentInstance.VALID));
+
+
+    }
+
+    private PrimitiveComponentType createAProvider() {
+        return new PrimitiveComponentType()
+                .setBundleContext(context)
+                .setClassName(FooImpl.class.getName())
+                .setPublic(true)
+                .addService(new Service()); // Provide the FooService
+    }
+
+    private PrimitiveComponentType createAConsumer() {
+        return new PrimitiveComponentType()
+                .setBundleContext(context)
+                .setClassName(MyComponentImpl.class.getName())
+                .addDependency(new Dependency().setField("myFoo"))
+                .setValidateMethod("start");
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/ExternalHandlerTest.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/ExternalHandlerTest.java
new file mode 100644
index 0000000..e478c79
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/ExternalHandlerTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.api.PrimitiveComponentType;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.runtime.core.api.components.HostImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+
+public class ExternalHandlerTest extends Common {
+
+
+    private BundleContext context;
+
+    @Before
+    public void setUp() {
+        context = getContext();
+    }
+
+    @Test
+    public void createAHost() throws Exception {
+        PrimitiveComponentType type = createAWhiteboardHost();
+        ComponentInstance ci = type.createInstance();
+        assertThat(ci.getState(), is(ComponentInstance.VALID));
+        HandlerDescription hd = ci.getInstanceDescription().getHandlerDescription(Whiteboard.NAMESPACE + ":" + Whiteboard.NAME);
+        assertThat(hd, is(notNullValue()));
+    }
+
+    @Test
+    public void createDoubleHost() throws Exception {
+        PrimitiveComponentType type = createASecondWhiteboardHost();
+        ComponentInstance ci = type.createInstance();
+        assertThat(ci.getState(), is(ComponentInstance.VALID));
+        HandlerDescription hd = ci.getInstanceDescription().getHandlerDescription(Whiteboard.NAMESPACE + ":" + Whiteboard.NAME);
+        assertThat(hd, is(notNullValue()));
+    }
+
+    private PrimitiveComponentType createAWhiteboardHost() {
+        return new PrimitiveComponentType()
+                .setBundleContext(context)
+                .setClassName(HostImpl.class.getName())
+                .addHandler(new Whiteboard()
+                        .onArrival("arrival")
+                        .onDeparture("departure")
+                        .setFilter("(foo=foo)")
+                );
+    }
+
+    private PrimitiveComponentType createASecondWhiteboardHost() {
+        return new PrimitiveComponentType()
+                .setBundleContext(context)
+                .setClassName(HostImpl.class.getName())
+                .addHandler(new Whiteboard()
+                        .onArrival("arrival")
+                        .onDeparture("departure")
+                        .setFilter("(foo=foo)")
+                )
+                .addHandler(new Whiteboard()
+                        .onArrival("arrival")
+                        .onDeparture("departure")
+                        .setFilter("(foo=bar)")
+                        .onModification("modification")
+                );
+    }
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/PrimitiveComponentTest.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/PrimitiveComponentTest.java
new file mode 100644
index 0000000..57423d8
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/PrimitiveComponentTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+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.api.Dependency;
+import org.apache.felix.ipojo.api.PrimitiveComponentType;
+import org.apache.felix.ipojo.api.Service;
+import org.apache.felix.ipojo.api.SingletonComponentType;
+import org.apache.felix.ipojo.runtime.core.api.components.FooImpl;
+import org.apache.felix.ipojo.runtime.core.api.components.MyComponentImpl;
+import org.apache.felix.ipojo.runtime.core.api.services.Foo;
+import org.junit.Before;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+
+public class PrimitiveComponentTest extends Common {
+
+    private BundleContext context;
+
+    @Before
+    public void setUp() {
+        context = getContext();
+    }
+
+    @Configuration
+    public Option[] config() throws IOException {
+        return super.config();
+    }
+
+    @Test
+    public void createAServiceProvider() throws Exception {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci;
+
+        PrimitiveComponentType type = createAProvider();
+        ci = type.createInstance();
+        assertThat("Ci is valid", ci.getState(), is(ComponentInstance.VALID));
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(Foo.class
+                .getName(), ci.getInstanceName());
+        assertThat(ref, is(notNullValue()));
+
+    }
+
+    @Test
+    public void killTheFactory() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci = null;
+
+        PrimitiveComponentType type = createAProvider();
+        ci = type.createInstance();
+        assertThat("Ci is valid", ci.getState(), is(ComponentInstance.VALID));
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(Foo.class
+                .getName(), ci.getInstanceName());
+        assertThat(ref, is(notNullValue()));
+        type.stop();
+        assertThat("Ci is disposed", ci.getState(),
+                is(ComponentInstance.DISPOSED));
+        ref = ipojoHelper.getServiceReferenceByName(Foo.class.getName(), ci
+                .getInstanceName());
+        assertThat(ref, is(nullValue()));
+
+    }
+
+    @Test
+    public void createAServiceCons() throws Exception {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci = null;
+
+        PrimitiveComponentType type = createAConsumer();
+        ci = type.createInstance();
+        assertThat("Ci is invalid", ci.getState(),
+                is(ComponentInstance.INVALID));
+
+    }
+
+    @Test
+    public void createBoth() throws Exception {
+        ComponentInstance cons = createAConsumer().createInstance();
+        // cons is invalid
+        assertThat("cons is invalid", cons.getState(), is(ComponentInstance.INVALID));
+
+        ComponentInstance prov = createAProvider().createInstance();
+        assertThat("prov is valid", prov.getState(), is(ComponentInstance.VALID));
+        assertThat("cons is valid", cons.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    @Test
+    public void createTwoCons() throws Exception {
+        ComponentInstance cons1 = createAConsumer().createInstance();
+        // cons is invalid
+        assertThat("cons is invalid", cons1.getState(), is(ComponentInstance.INVALID));
+
+        ComponentInstance prov = createAProvider().createInstance();
+        assertThat("prov is valid", prov.getState(), is(ComponentInstance.VALID));
+        assertThat("cons is valid", cons1.getState(), is(ComponentInstance.VALID));
+
+        ComponentInstance cons2 = createAnOptionalConsumer().createInstance();
+
+        assertThat("cons2 is valid", cons2.getState(), is(ComponentInstance.VALID));
+
+        prov.stop();
+        assertThat("cons is invalid", cons1.getState(), is(ComponentInstance.INVALID));
+        assertThat("cons2 is valid", cons2.getState(), is(ComponentInstance.VALID));
+    }
+
+    private PrimitiveComponentType createAProvider() {
+        return new PrimitiveComponentType()
+                .setBundleContext(context)
+                .setClassName(FooImpl.class.getName())
+                .addService(new Service()); // Provide the FooService
+    }
+
+    private PrimitiveComponentType createAConsumer() {
+        return new SingletonComponentType()
+                .setBundleContext(context)
+                .setClassName(MyComponentImpl.class.getName())
+                .addDependency(new Dependency().setField("myFoo"))
+                .setValidateMethod("start");
+    }
+
+    private PrimitiveComponentType createAnOptionalConsumer() {
+        return new SingletonComponentType()
+                .setBundleContext(context)
+                .setComponentTypeName("cons.optional")
+                .setClassName(MyComponentImpl.class.getName())
+                .addDependency(new Dependency().setField("myFoo").setOptional(true))
+                .setValidateMethod("start");
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/SingletonComponentTest.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/SingletonComponentTest.java
new file mode 100644
index 0000000..323b2dd
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/SingletonComponentTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+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.api.Dependency;
+import org.apache.felix.ipojo.api.PrimitiveComponentType;
+import org.apache.felix.ipojo.api.Service;
+import org.apache.felix.ipojo.api.SingletonComponentType;
+import org.apache.felix.ipojo.runtime.core.api.components.FooImpl;
+import org.apache.felix.ipojo.runtime.core.api.components.MyComponentImpl;
+import org.apache.felix.ipojo.runtime.core.api.services.Foo;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+
+public class SingletonComponentTest extends Common {
+
+    private BundleContext context;
+
+    @Before
+    public void setUp() {
+        context = getContext();
+    }
+
+    @Test
+    public void createAServiceProvider() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci = null;
+
+        SingletonComponentType type = createAProvider();
+        ci = type.create();
+        assertThat("Ci is valid", ci.getState(), is(ComponentInstance.VALID));
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(Foo.class
+                .getName(), ci.getInstanceName());
+        assertThat(ref, is(notNullValue()));
+        type.disposeInstance(ci);
+
+    }
+
+    @Test
+    public void killTheFactory() throws Exception {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci = null;
+        SingletonComponentType type = createAProvider();
+        ci = type.create();
+        assertThat("Ci is valid", ci.getState(), is(ComponentInstance.VALID));
+        ServiceReference ref = ipojoHelper.getServiceReferenceByName(Foo.class
+                .getName(), ci.getInstanceName());
+        assertThat(ref, is(notNullValue()));
+        type.stop();
+        assertThat("Ci is disposed", ci.getState(),
+                is(ComponentInstance.DISPOSED));
+        ref = ipojoHelper.getServiceReferenceByName(Foo.class.getName(), ci
+                .getInstanceName());
+        assertThat(ref, is(nullValue()));
+    }
+
+    @Test
+    public void createAServiceCons() throws Exception {
+        assertThat(context, is(notNullValue()));
+        ComponentInstance ci = null;
+
+        SingletonComponentType type = createAConsumer();
+        ci = type.create();
+        assertThat("Ci is invalid", ci.getState(),
+                is(ComponentInstance.INVALID));
+        type.stop();
+    }
+
+    @Test
+    public void createBoth() throws Exception {
+        SingletonComponentType consFactory = createAConsumer();
+        ComponentInstance cons = consFactory.create();
+        // cons is invalid
+        assertThat("cons is invalid", cons.getState(), is(ComponentInstance.INVALID));
+
+        SingletonComponentType provFactory = createAProvider();
+        ComponentInstance prov = provFactory.create();
+        assertThat("prov is valid", prov.getState(), is(ComponentInstance.VALID));
+        assertThat("cons is valid", cons.getState(), is(ComponentInstance.VALID));
+        consFactory.stop();
+        provFactory.stop();
+    }
+
+    @Test
+    public void createTwoCons() throws Exception {
+        SingletonComponentType consFactory = createAConsumer();
+        ComponentInstance cons1 = createAConsumer().create();
+        // cons is invalid
+        assertThat("cons is invalid", cons1.getState(), is(ComponentInstance.INVALID));
+
+        ComponentInstance prov = createAProvider().create();
+        assertThat("prov is valid", prov.getState(), is(ComponentInstance.VALID));
+        assertThat("cons is valid", cons1.getState(), is(ComponentInstance.VALID));
+
+        ComponentInstance cons2 = createAnOptionalConsumer().create();
+
+        assertThat("cons2 is valid", cons2.getState(), is(ComponentInstance.VALID));
+
+        prov.stop();
+        assertThat("cons is invalid", cons1.getState(), is(ComponentInstance.INVALID));
+        assertThat("cons2 is valid", cons2.getState(), is(ComponentInstance.VALID));
+    }
+
+    @Test
+   // @Ignore("We can't test as the MyComponentImpl must be manipulated before creating the object")
+    public void setObject() throws Exception {
+        ComponentInstance cons = createAConsumer().setObject(new MyComponentImpl(5)).create();
+        // cons is invalid
+        assertThat("cons is invalid", cons.getState(), is(ComponentInstance.INVALID));
+
+        ComponentInstance prov = createAProvider().create();
+        assertThat("prov is valid", prov.getState(), is(ComponentInstance.VALID));
+        assertThat("cons is valid", cons.getState(), is(ComponentInstance.VALID));
+
+    }
+
+    private SingletonComponentType createAProvider() {
+        PrimitiveComponentType type = new SingletonComponentType()
+                .setBundleContext(context)
+                .setClassName(FooImpl.class.getName())
+                .addService(new Service()); // Provide the FooService
+
+        return (SingletonComponentType) type;
+    }
+
+    private SingletonComponentType createAConsumer() {
+        PrimitiveComponentType type = new SingletonComponentType()
+                .setBundleContext(context)
+                .setClassName(MyComponentImpl.class.getName())
+                .setComponentTypeName("singleton.cons")
+                .addDependency(new Dependency().setField("myFoo"))
+                .setValidateMethod("start");
+
+        return (SingletonComponentType) type;
+    }
+
+    private SingletonComponentType createAnOptionalConsumer() {
+        PrimitiveComponentType type = new SingletonComponentType()
+                .setBundleContext(context)
+                .setClassName(MyComponentImpl.class.getName())
+                .addDependency(new Dependency().setField("myFoo").setOptional(true))
+                .setComponentTypeName("singleton.optional.consumer")
+                .setValidateMethod("start");
+
+        return (SingletonComponentType) type;
+
+    }
+
+
+}
diff --git a/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Whiteboard.java b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Whiteboard.java
new file mode 100644
index 0000000..77caf6b
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-api-test/src/test/java/org/apache/felix/ipojo/runtime/core/api/Whiteboard.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.api;
+
+import org.apache.felix.ipojo.api.HandlerConfiguration;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class Whiteboard implements HandlerConfiguration {
+    
+    public static final String NAME = "wbp";
+    
+    public static final String NAMESPACE = "org.apache.felix.ipojo.whiteboard";
+    
+    private String arrival;
+    
+    private String departure;
+    
+    private String modification;
+    
+    private String filter;
+    
+    public Whiteboard onArrival(String method) {
+        arrival = method;
+        return this;
+    }
+    
+    public Whiteboard onDeparture(String method) {
+        departure = method;
+        return this;
+    }
+    
+    public Whiteboard onModification(String method) {
+        modification = method;
+        return this;
+    }
+    
+    public Whiteboard setFilter(String fil) {
+        filter = fil;
+        return this;
+    }
+
+    public Element getElement() {
+        ensureValidity();
+        // Create the root element.
+        Element element = new Element(NAME, NAMESPACE);
+        // Mandatory attributes
+        element.addAttribute(new Attribute("onArrival", arrival));
+        element.addAttribute(new Attribute("onDeparture", departure));
+        element.addAttribute(new Attribute("filter", filter));
+        
+        // Optional attribute
+        if (modification != null) {
+            element.addAttribute(new Attribute("onModification", modification));
+        }        
+        
+        return element;
+    }
+
+    private void ensureValidity() {
+        if (arrival == null) {
+            throw new IllegalStateException("The whiteboard pattern configuration must have a onArrival method");
+        }
+        if (departure == null) {
+            throw new IllegalStateException("The whiteboard pattern configuration must have a onDeparture method");
+        }
+        if (filter == null) {
+            throw new IllegalStateException("The whiteboard pattern configuration must have a filter");
+        }
+        
+    }
+
+}