reworked annotation junit tests

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@911575 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AnnotationBase.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AnnotationBase.java
new file mode 100644
index 0000000..6944070
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AnnotationBase.java
@@ -0,0 +1,103 @@
+/*
+* 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.dm.test.annotation;
+
+import org.apache.felix.dm.test.Base;
+import org.apache.felix.dm.test.Ensure;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+/**
+ * Base class for all annotation junit test classes. This class allows to parse annotations
+ * from a dynamically generated "TinyBundle". The class also implements a Sequencer interface, 
+ * which wraps a "Ensure" object. The Sequencer will be used directly by the tiny bundles, in order to
+ * check that steps happen in the expected order. 
+ */
+public class AnnotationBase extends Base implements Sequencer
+{
+    /**
+     * The object used to check if expected steps happen in the correct order.
+     */
+    protected Ensure m_ensure = new Ensure();
+
+    /**
+     * Helper method used to stop a given bundle.
+     * @param symbolicName the symbolic name of the bundle to be stopped.
+     * @param context the context of the bundle to be stopped.
+     */
+    protected void stopBundle(String symbolicName, BundleContext context)
+    {
+        // Stop the test.annotation bundle
+        boolean found = false;
+        for (Bundle b : context.getBundles())
+        {
+            if (b.getSymbolicName().equals(symbolicName))
+            {
+                try
+                {
+                    found = true;
+                    b.stop();
+                }
+                catch (BundleException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (!found)
+        {
+            throw new IllegalStateException("bundle " + symbolicName + " not found");
+        }
+    }
+
+    /**
+     * Suspend the current thread for a while.
+     * @param n the number of milliseconds to wait for.
+     */
+    protected void sleep(int ms)
+    {
+        try
+        {
+            Thread.sleep(ms);
+        }
+        catch (InterruptedException e)
+        {
+        }
+    }
+
+    // ----------------------- Sequencer interface ------------------------------------------
+
+    /**
+     * Crosses a given step number.
+     */
+    public void step(int step)
+    {
+        m_ensure.step(step);
+    }
+
+    /**
+     * Waits for a given step to happen.
+     */
+    public void waitForStep(int nr, int timeout)
+    {
+        m_ensure.waitForStep(nr, timeout);
+    }
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectAnnotationTest.java
new file mode 100644
index 0000000..dc89d3a
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectAnnotationTest.java
@@ -0,0 +1,78 @@
+/*
+* 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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Verify Aspect Annotations usage.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class AspectAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                    .set(Constants.BUNDLE_SYMBOLICNAME, "AspectTest")
+                    .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                    .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.aspect")
+                    .set("Import-Package", "*")
+                    .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                    .build()));           
+    }
+
+    @Test
+    public void testAnnotatedAspect(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // Provide the Sequencer to the "ServiceProvider" service (see main/src/.../AspectTest.java). 
+        Dictionary props = new Hashtable() {{ put("test", "aspect.ServiceProvider"); }};
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), props));
+        // Check if the ServiceProvider has been injected in the AspectTest service.
+        m_ensure.waitForStep(1, 10000);
+        // Provide the Sequencer for activating the ServiceProviderAspect service
+        props = new Hashtable() {{ put("test", "aspect.ServiceProviderAspect"); }};
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), props));
+        // And check if the AspectTest has been injected with the aspect
+        m_ensure.waitForStep(2, 10000);
+    }
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectLifecycleAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectLifecycleAnnotationTest.java
new file mode 100644
index 0000000..3a72c2c
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AspectLifecycleAnnotationTest.java
@@ -0,0 +1,83 @@
+/*
+* 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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Tests an aspect service, and ensure that its lifecycle methods are properly invoked 
+ * (init/start/stop/destroy methods).
+ */
+@RunWith(JUnit4TestRunner.class)
+public class AspectLifecycleAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                    .set(Constants.BUNDLE_SYMBOLICNAME, "AspectLifecycleTest")
+                    .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                    .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.aspectlifecycle")
+                    .set("Import-Package", "*")
+                    .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                    .build()));         
+    }
+
+    @Test
+    public void testAnnotatedAspect(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // Provide the Sequencer server to the AspectLifecycleTest$ServiceProvider service
+        Dictionary props = new Hashtable() {{ put("test", "aspectLifecycle.ServiceProvider"); }};
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), props));
+        // Check if the ServiceProvider has been injected in the AspectTest service.
+        m_ensure.waitForStep(1, 10000);
+        // Provide the Sequencer server to the AspectLifecycleTest$ServiceProviderAspect service
+        props = new Hashtable() {{ put("test", "aspectLifecycle.ServiceProviderAspect"); }};
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), props));
+        // Check if the AspectTest has been injected with the aspect
+        m_ensure.waitForStep(3, 10000);
+        // Stop the test.annotation bundle.
+        stopBundle("AspectLifecycleTest", context);
+        // And check if the aspect has been called in its stop/destroy methods.
+        m_ensure.waitForStep(6, 10000);
+    }
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryAnnotationTest.java
new file mode 100644
index 0000000..265f857
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryAnnotationTest.java
@@ -0,0 +1,69 @@
+/*
+* 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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Ensure that a service can be instantiated by another Factory class.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class FactoryAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                    .set(Constants.BUNDLE_SYMBOLICNAME, "FactoryAnnotationTest")
+                    .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                    .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.factory")
+                    .set("Import-Package", "*")
+                    .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                    .build()));            
+    }
+
+    @Test
+    public void testSimpleAnnotations(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // Provider the Sequencer service to the FactoryTest service.
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), null));
+        // Check if the test.annotation components have been initialized orderly
+        m_ensure.waitForStep(1, 10000);
+    }    
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/MultipleAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/MultipleAnnotationTest.java
new file mode 100644
index 0000000..138f0d1
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/MultipleAnnotationTest.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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Verify complex Annotation usage.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class MultipleAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                    .set(Constants.BUNDLE_SYMBOLICNAME, "MultipleAnnotationTest")
+                    .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                    .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.multiple")
+                    .set("Import-Package", "*")
+                    .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                    .build()));            
+    }
+
+    @Test
+    public void testComplexAnnotations(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // Provide the Sequencer service to the MultipleAnnotationTest class.
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), null));
+        // Check if the test.annotation components have been initialized orderly
+        m_ensure.waitForStep(7, 10000);
+        // Stop the test.annotation bundle
+        stopBundle("MultipleAnnotationTest", context);
+        // And check if the test.annotation bundle has been deactivated orderly
+        m_ensure.waitForStep(11, 10000);
+    }
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/SimpleAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/SimpleAnnotationTest.java
new file mode 100644
index 0000000..27afaa8
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/SimpleAnnotationTest.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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Ensure that a Provider can be injected into a Consumer, using simple DM annotations.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class SimpleAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                   .set(Constants.BUNDLE_SYMBOLICNAME, "SimpleAnnotationTest")
+                   .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                   .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.simple")
+                   .set("Import-Package", "*")
+                   .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                   .build()));
+    }
+
+    @Test
+    public void testSimpleAnnotations(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // We provide ourself as a "Sequencer" service to the annotated bundles. 
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), null));
+        // Check if the test.annotation components have been initialized orderly
+        m_ensure.waitForStep(3, 10000);
+        // Stop our annotation bundle.
+        stopBundle("SimpleAnnotationTest", context);
+        // And check if components have been deactivated orderly.
+        m_ensure.waitForStep(5, 10000);
+    }        
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/TemporalAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/TemporalAnnotationTest.java
new file mode 100644
index 0000000..27d6b4e
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/TemporalAnnotationTest.java
@@ -0,0 +1,89 @@
+/*
+* 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.dm.test.annotation;
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.service.Service;
+import org.apache.felix.dm.test.BundleGenerator;
+import org.apache.felix.dm.test.Ensure;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Use case: Verify Temporal Service Dependendency Annotations usage.
+ */
+@RunWith(JUnit4TestRunner.class)
+public class TemporalAnnotationTest extends AnnotationBase
+{
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
+            provision(
+                new BundleGenerator()
+                    .set(Constants.BUNDLE_SYMBOLICNAME, "TemporalTest")
+                    .set("Export-Package", "org.apache.felix.dm.test.bundle.annotation.sequencer")
+                    .set("Private-Package", "org.apache.felix.dm.test.bundle.annotation.temporal")
+                    .set("Import-Package", "*")
+                    .set("-plugin", "org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin")
+                    .build()));            
+    }
+
+    @Test
+    public void testTemporalServiceDependency(BundleContext context)
+    {
+        DependencyManager m = new DependencyManager(context);
+        // Provide the Sequencer service to the TemporalServiceDependencyTest service. 
+        m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(), null));
+                 
+        Runnable r = Ensure.createRunnableStep(m_ensure, 1);
+        Dictionary props = new Hashtable() {{ put("test", "temporal"); }};
+        Service s = m.createService().setImplementation(r).setInterface(Runnable.class.getName(), props);        
+        m.add(s);
+        m_ensure.waitForStep(1, 15000);
+        m.remove(s);
+        m_ensure.step(2);
+        sleep(500);
+        r = Ensure.createRunnableStep(m_ensure, 3);
+        s = m.createService().setImplementation(r).setInterface(Runnable.class.getName(), props);
+        m.add(s);
+        m_ensure.waitForStep(3, 15000);
+        m.remove(s);
+        m_ensure.step(4);
+        sleep(1500);
+        m_ensure.waitForStep(5, 15000);
+    }
+}