[FELIX-2966] - Annotations should automatically generate Import-Service/Export-Service headers.
[FELIX-2965] - Annotations should allow to enable or disable auto-configuration mode.



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1125833 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/annotation/doc/changelog.txt b/dependencymanager/annotation/doc/changelog.txt
index a47f495..0ea1c46 100644
--- a/dependencymanager/annotation/doc/changelog.txt
+++ b/dependencymanager/annotation/doc/changelog.txt
@@ -5,9 +5,11 @@
 
 ** Improvement
 
-    * removed changelog.txt from root of project
+    * Removed changelog.txt from root of project
     * [FELIX-2954] - annotated component factory does not allow to provide a component instance explicitly
     * [FELIX-2956] - json should be embedded in the annotation scanner plugin
+    * [FELIX-2966] - Annotations should automatically generate Import-Service/Export-Service headers
+    * [FELIX-2965] - Annotations should allow to enable or disable auto-configuration mode.
 
 Initial Release 3.0.0
 ---------------------
diff --git a/dependencymanager/annotation/pom.xml b/dependencymanager/annotation/pom.xml
index bbf8abc..0a08432 100644
--- a/dependencymanager/annotation/pom.xml
+++ b/dependencymanager/annotation/pom.xml
@@ -29,7 +29,7 @@
 	<name>Apache Felix Dependency Manager Annotation</name>
 	<description>Dependency Manager Annotation API and corresponding scanner plugins</description>
 	<artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
-	<version>3.0.1-SNAPSHOT</version>
+	<version>3.1.0-SNAPSHOT</version>
 	<packaging>maven-plugin</packaging>
 	<dependencies>
 		<dependency>
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Component.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Component.java
index 780b8f4..d756b31 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Component.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Component.java
@@ -186,8 +186,8 @@
     /**
      * Sets the static method used to create the components implementation instance.
      */
-    String factoryMethod() default "";    
-    
+    String factoryMethod() default "";
+        
     /**
      * Service property name used to match a given Factory Set.
      * @see #factorySet() for more information about factory sets.
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
index ab144c3..958e16a 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
@@ -37,12 +37,15 @@
 import org.apache.felix.dm.annotation.api.Destroy;
 import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
 import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.LifecycleController;
 import org.apache.felix.dm.annotation.api.ResourceAdapterService;
 import org.apache.felix.dm.annotation.api.ResourceDependency;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.annotation.api.Registered;
 import org.apache.felix.dm.annotation.api.Stop;
+import org.apache.felix.dm.annotation.api.Unregistered;
 import org.osgi.framework.Bundle;
 
 import aQute.lib.osgi.Annotation;
@@ -75,6 +78,9 @@
     private final static String A_BUNDLE_ADAPTER_SERVICE = "L" + BundleAdapterService.class.getName().replace('.', '/') + ";";
     private final static String A_RESOURCE_ADAPTER_SERVICE = "L" + ResourceAdapterService.class.getName().replace('.', '/') + ";";
     private final static String A_FACTORYCONFIG_ADAPTER_SERVICE = "L" + FactoryConfigurationAdapterService.class.getName().replace('.', '/') + ";";
+    private final static String A_INJECT = "L" + Inject.class.getName().replace('.', '/') + ";";
+    private final static String A_REGISTERED = "L" + Registered.class.getName().replace('.', '/') + ";";
+    private final static String A_UNREGISTERED = "L" + Unregistered.class.getName().replace('.', '/') + ";";
 
     private Logger m_logger;
     private String m_className;
@@ -94,6 +100,13 @@
     private String m_compositionMethod;
     private String m_starter;
     private String m_stopper;
+    private Set<String> m_importService = new HashSet<String>();
+    private Set<String> m_exportService = new HashSet<String>();
+    private String m_bundleContextField;
+    private String m_dependencyManagerField;
+    private String m_componentField;
+    private String m_registeredMethod;
+    private String m_unregisteredMethod;
 
     /**
      * This class represents a DependencyManager component descriptor entry.
@@ -201,10 +214,18 @@
         {
             m_startMethod = m_method;
         } 
+        else if (annotation.getName().equals(A_REGISTERED))
+        {
+            m_registeredMethod = m_method;
+        }
         else if (annotation.getName().equals(A_STOP))
         {
             m_stopMethod = m_method;
         }
+        else if (annotation.getName().equals(A_UNREGISTERED))
+        {
+            m_unregisteredMethod = m_method;
+        }
         else if (annotation.getName().equals(A_DESTROY))
         {
             m_destroyMethod = m_method;
@@ -232,6 +253,10 @@
         else if (annotation.getName().equals(A_RESOURCE_DEPENDENCY))
         {
             parseRersourceDependencyAnnotation(annotation);
+        } 
+        else if (annotation.getName().equals(A_INJECT))
+        {
+            parseInject(annotation);
         }
     }
 
@@ -276,12 +301,32 @@
         }
     }
         
+    /**
+     * Returns list of all imported services. Imported services are deduced from every
+     * @ServiceDependency annotations.
+     * @return the list of imported services, or null
+     */
+    public Set<String> getImportService()
+    {
+        return m_importService;
+    }
+
+    /**
+     * Returns list of all exported services. Imported services are deduced from every
+     * annotations which provides a service (@Component, etc ...)
+     * @return the list of exported services, or null
+     */
+    public Set<String> getExportService()
+    {
+        return m_exportService;
+    }
+
     private void parseComponentAnnotation(Annotation annotation)
     {
         EntryWriter writer = new EntryWriter(EntryType.Component);
         m_writers.add(writer);
 
-        // Register previously parsed Init/Start/Stop/Destroy/Composition annotations
+        // Register previously parsed annotations common to services (Init/Start/...)
         addCommonServiceParams(writer);
 
         // impl attribute
@@ -291,10 +336,19 @@
         parseProperties(annotation, EntryParam.properties, writer);
 
         // provides attribute
-        writer.putClassArray(annotation, EntryParam.provides, m_interfaces);
+        writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService);
 
         // factorySet attribute
-        writer.putString(annotation, EntryParam.factorySet, null);
+        String factorySetName = writer.putString(annotation, EntryParam.factorySet, null);
+        if (factorySetName != null)
+        {
+            // When a component defines a factorySet, it means that a java.util.Set will 
+            // be provided into the OSGi registry, in order to let anoter component add
+            // some component instance configurations into it.
+            // So, we have to indicate that the Set is provided as a service, in the Export-Serviec
+            // header.
+            m_exportService.add("java.util.Set");
+        }
 
         // factoryConfigure attribute
         writer.putString(annotation, EntryParam.factoryConfigure, null);
@@ -314,11 +368,21 @@
         {
             writer.put(EntryParam.start, m_startMethod);
         }
+        
+        if (m_registeredMethod != null)
+        {
+            writer.put(EntryParam.registered, m_registeredMethod);
+        }
 
         if (m_stopMethod != null)
         {
             writer.put(EntryParam.stop, m_stopMethod);
         }
+        
+        if (m_unregisteredMethod != null)
+        {
+            writer.put(EntryParam.unregistered, m_unregisteredMethod);
+        }
 
         if (m_destroyMethod != null)
         {
@@ -344,6 +408,21 @@
                                                    "@LifecycleController that starts the component in class " + m_className);
             }
         }   
+
+        if (m_bundleContextField != null)
+        {
+            writer.put(EntryParam.bundleContextField, m_bundleContextField);
+        }
+        
+        if (m_dependencyManagerField != null)
+        {
+            writer.put(EntryParam.dependencyManagerField, m_dependencyManagerField);
+        }
+        
+        if (m_componentField != null)
+        {
+            writer.put(EntryParam.componentField, m_componentField);
+        }
     }
 
     /**
@@ -374,6 +453,9 @@
         }
         writer.put(EntryParam.service, service);
 
+        // Store this service in list of imported services.
+        m_importService.add(service);
+        
         // autoConfig attribute
         if (m_isField)
         {
@@ -562,7 +644,7 @@
         parseProperties(annotation, EntryParam.properties, writer);
 
         // Parse the provided adapter service (use directly implemented interface by default).
-        writer.putClassArray(annotation, EntryParam.provides, m_interfaces);
+        writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService);
         
         // Parse factoryMethod attribute
         writer.putString(annotation, EntryParam.factoryMethod, null);
@@ -602,7 +684,7 @@
         parseProperties(annotation, EntryParam.properties, writer);
 
         // Parse the optional adapter service (use directly implemented interface by default).
-        writer.putClassArray(annotation, EntryParam.provides, m_interfaces);
+        writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService);
 
         // Parse propagate attribute
         writer.putString(annotation, EntryParam.propagate, Boolean.FALSE.toString());
@@ -638,7 +720,7 @@
         parseProperties(annotation, EntryParam.properties, writer);
 
         // Parse the provided adapter service (use directly implemented interface by default).
-        writer.putClassArray(annotation, EntryParam.provides, m_interfaces);
+        writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService);
 
         // Parse propagate attribute
         writer.putString(annotation, EntryParam.propagate, Boolean.FALSE.toString());
@@ -672,7 +754,7 @@
         writer.putString(annotation, EntryParam.propagate, Boolean.FALSE.toString());
 
         // Parse the provided adapter service (use directly implemented interface by default).
-        writer.putClassArray(annotation, EntryParam.provides, m_interfaces);
+        writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService);
 
         // Parse Adapter properties.
         parseProperties(annotation, EntryParam.properties, writer);
@@ -752,7 +834,7 @@
     
     private void parseLifecycleAnnotation(Annotation annotation)
     {
-        Patterns.parseField(m_field, m_descriptor, Patterns.Runnable);
+        Patterns.parseField(m_field, m_descriptor, Patterns.RUNNABLE);
         if ("true".equals(get(annotation,EntryParam.start.name(), "true")))
         {
             if (m_starter != null) {
@@ -773,7 +855,6 @@
      * Parse optional meta types annotation attributes
      * @param annotation
      */
-    @SuppressWarnings("null")
     private void parseMetaTypes(Annotation annotation, String pid, boolean factory)
     {
         if (annotation.get("metadata") != null)
@@ -870,7 +951,33 @@
             writer.putProperties(attribute, properties);
         }
     }
-
+    
+    /**
+     * Parse Inject annotation, used to inject some special classes in some fields
+     * (BundleContext/DependencyManager etc ...)
+     * @param annotation the Inject annotation
+     */
+    private void parseInject(Annotation annotation)
+    {      
+        if (Patterns.BUNDLE_CONTEXT.matcher(m_descriptor).matches())
+        {
+            m_bundleContextField = m_field;
+        }
+        else if (Patterns.DEPENDENCY_MANAGER.matcher(m_descriptor).matches())
+        {
+            m_dependencyManagerField = m_field;
+        }
+        else if (Patterns.COMPONENT.matcher(m_descriptor).matches())
+        {
+            m_componentField = m_field;
+        }
+        else
+        {
+            throw new IllegalArgumentException("@Inject annotation can't be applied on the field \"" + m_field
+                                               + "\" in class " + m_className);
+        }
+    }
+    
     /**
      * Checks if the class is annotated with some given annotations. Notice that the Service
      * is always parsed at end of parsing, so, we have to check the last element of our m_writers
@@ -913,5 +1020,5 @@
     {
         T value = (T) annotation.get(name);
         return value != null ? value : defaultValue;
-    }        
+    }
 }
\ No newline at end of file
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationPlugin.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationPlugin.java
index 5813370..35c9077 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationPlugin.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationPlugin.java
@@ -22,6 +22,7 @@
 import java.io.StringWriter;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import aQute.bnd.service.AnalyzerPlugin;
 import aQute.bnd.service.Plugin;
@@ -38,8 +39,11 @@
  */
 public class AnnotationPlugin implements AnalyzerPlugin, Plugin
 {
+    private static final String IMPORT_SERVICE = "Import-Service";
+    private static final String EXPORT_SERVICE = "Export-Service";
     private BndLogger m_logger;
     private Reporter m_reporter;
+    private boolean m_buildImportExportService;
 
     /**
      * This plugin is called after analysis of the JAR but before manifest
@@ -62,6 +66,22 @@
             {
                 // We have parsed some annotations: set the OSGi "DependencyManager-Component" header in the target bundle.
                 analyzer.setProperty("DependencyManager-Component", generator.getDescriptorPaths());
+                
+                // Possibly set the Import-Service/Export-Service header
+                if (m_buildImportExportService)
+                {
+                    // Don't override Import-Service header, if it is found from the bnd directives.
+                    if (analyzer.getProperty(IMPORT_SERVICE) == null)
+                    {
+                        buildImportExportService(analyzer, IMPORT_SERVICE, generator.getImportService());
+                    }
+                    
+                    // Don't override Export-Service header, if already defined
+                    if (analyzer.getProperty(EXPORT_SERVICE) == null)
+                    {
+                        buildImportExportService(analyzer, EXPORT_SERVICE, generator.getExportService());
+                    }
+                }
 
                 // And insert the generated descriptors into the target bundle.
                 Map<String, Resource> resources = generator.getDescriptors();
@@ -112,10 +132,32 @@
         return false;
     }
 
+    private void buildImportExportService(Analyzer analyzer, String header, Set<String> services)
+    {
+        m_logger.info("building %s header with the following services: %s", header, services);
+        if (services.size() > 0)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (String service : services)
+            {
+                sb.append(service);
+                sb.append(",");
+            }
+            sb.setLength(sb.length() - 1); // skip last comma
+            analyzer.setProperty(header, sb.toString());
+        } 
+    }
+
     public void setProperties(Map<String, String> map)
     {
         String logLevel = map.get("log");
         m_logger = new BndLogger(logLevel == null ? "error" : logLevel);
+        String generateImportExportService = map.get("build-import-export-service");
+        if (generateImportExportService == null)
+        {
+            generateImportExportService = "true";
+        }
+        m_buildImportExportService = Boolean.parseBoolean(generateImportExportService);
     }
 
     public void setReporter(Reporter reporter)
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/DescriptorGenerator.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/DescriptorGenerator.java
index 06d9585..d61d4de 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/DescriptorGenerator.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/DescriptorGenerator.java
@@ -24,7 +24,9 @@
 import java.io.PrintWriter;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import aQute.lib.osgi.Analyzer;
 import aQute.lib.osgi.Clazz;
@@ -62,6 +64,16 @@
     private final Logger m_logger;
 
     /**
+     * List of imported services found from every ServiceDependency annotations.
+     */
+    private Set<String> m_importService = new HashSet<String>();
+
+    /**
+     * List of exported services found from every service providing components.
+     */
+    private Set<String> m_exportService = new HashSet<String>();
+
+    /**
      * Creates a new descriptor generator.
      * @param analyzer The bnd analyzer used to lookup classes containing DM annotations.
      * @param debug 
@@ -103,6 +115,9 @@
                 Resource resource = createComponentResource(reader);
                 m_resources.put("META-INF/dependencymanager/" + name, resource);
                 annotationsFound = true;
+                
+                m_importService.addAll(reader.getImportService());
+                m_exportService.addAll(reader.getExportService());
             }
         }
 
@@ -148,6 +163,26 @@
     }
     
     /**
+     * Returns set of all imported services. Imported services are deduced from every
+     * @ServiceDependency annotations.
+     * @return the list of imported services
+     */
+    public Set<String> getImportService()
+    {
+        return m_importService;
+    }
+
+    /**
+     * Returns set of all exported services. Imported services are deduced from every
+     * annotations which provides a service (@Component, etc ...)
+     * @return the list of exported services
+     */
+    public Set<String> getExportService()
+    {
+        return m_exportService;
+    }    
+
+    /**
      * Creates a bnd resource that contains the generated dm descriptor.
      * @param collector 
      * @return
@@ -179,5 +214,5 @@
         byte[] data = out.toByteArray();
         out.close();
         return new EmbeddedResource(data, 0);    
-    }    
+    }
 }
\ No newline at end of file
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java
index 1bc69a6..97a9ee9 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java
@@ -57,4 +57,9 @@
     name, 
     starter,
     stopper,
+    bundleContextField, 
+    dependencyManagerField, 
+    componentField, 
+    registered, 
+    unregistered
 }
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
index 493649c..2a02076 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
@@ -20,6 +20,7 @@
 
 import java.util.Arrays;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.json.JSONArray;
@@ -150,7 +151,7 @@
     /**
      * Get a String attribute value from an annotation and write it into this descriptor entry.
      */
-    public void putString(Annotation annotation, EntryParam param, String def)
+    public String putString(Annotation annotation, EntryParam param, String def)
     {
         checkType(param.toString());
         Object value = annotation.get(param.toString());
@@ -162,6 +163,7 @@
         {
             put(param, value.toString());
         }
+        return value == null ? null : value.toString();
     }
 
     /**
@@ -218,8 +220,9 @@
 
     /**
      * Get a class array attribute value from an annotation and write it into this descriptor entry.
+     * Also collect classes found from the array into a given Set.
      */
-    public void putClassArray(Annotation annotation, EntryParam param, Object def)
+    public void putClassArray(Annotation annotation, EntryParam param, Object def, Set<String> collect)
     {
         checkType(param.toString());
 
@@ -247,6 +250,7 @@
                 try
                 {
                     m_json.append(param.toString(), v.toString());
+                    collect.add(v.toString());
                 }
                 catch (JSONException e)
                 {
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
index 5a8f657..4def6b9 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
@@ -41,7 +41,16 @@
     public final static Pattern CLASS = Pattern.compile("L([^;]+);");
     
     // Pattern used to parse the field on which a Publisher annotation may be applied on
-    public final static Pattern Runnable = Pattern.compile("Ljava/lang/Runnable;");
+    public final static Pattern RUNNABLE = Pattern.compile("Ljava/lang/Runnable;");
+    
+    // Pattern used to parse a field whose type is BundleContext
+    public final static Pattern BUNDLE_CONTEXT = Pattern.compile("Lorg/osgi/framework/BundleContext;");
+
+    // Pattern used to parse a field whose type is DependencyManager
+    public final static Pattern DEPENDENCY_MANAGER = Pattern.compile("Lorg.apache.felix.dm.DependencyManager;");
+    
+    // Pattern used to parse a field whose type is Component
+    public final static Pattern COMPONENT = Pattern.compile("Lorg.apache.felix.dm.Component;");
 
     /**
      * Parses a class.
diff --git a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/mvn/AnnotationMojo.java b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/mvn/AnnotationMojo.java
index 4d0b77b..b7aad0f 100644
--- a/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/mvn/AnnotationMojo.java
+++ b/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/mvn/AnnotationMojo.java
@@ -19,7 +19,9 @@
 package org.apache.felix.dm.annotation.plugin.mvn;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.felix.dm.annotation.plugin.bnd.DescriptorGenerator;
 import org.apache.maven.model.Build;
@@ -59,7 +61,7 @@
      * @required
      */
     private String m_artifactExtension;
-    
+
     /**
      * If set, configures the log level.
      *
@@ -68,6 +70,23 @@
     private String m_log;
 
     /**
+     * If set, configures if we must auto generate Import-Service/Export-Service headers.
+     *
+     * @parameter alias="build-import-export-service"
+     */
+    private boolean m_buildImportExportService;
+
+    /**
+     * "Import-Service" osgi header
+     */
+    private static final String IMPORT_SERVICE = "Import-Service";
+
+    /**
+     * "Export-Service" osgi header
+     */
+    private static final String EXPORT_SERVICE = "Export-Service";
+
+    /**
      * Executes this mojo. We'll use the bnd library in order to scan classes from our target bundle.
      */
     public void execute() throws MojoExecutionException
@@ -96,7 +115,7 @@
                 // Add the list of generated component descriptors in our special header.
                 jar = analyzer.getJar();
                 jar.getManifest().getMainAttributes().putValue("DependencyManager-Component",
-                    generator.getDescriptorPaths());
+                                                               generator.getDescriptorPaths());
 
                 // Add generated descriptors into the target bundle (we'll use a temp file).
                 Map<String, Resource> resources = generator.getDescriptors();
@@ -104,11 +123,29 @@
                 {
                     jar.putResource(entry.getKey(), entry.getValue());
                 }
-                
+
                 Resource metaType = generator.getMetaTypeResource();
-                if (metaType != null) {
+                if (metaType != null)
+                {
                     jar.putResource("OSGI-INF/metatype/metatype.xml", metaType);
                 }
+
+                // Possibly set the Import-Service/Export-Service header
+                if (m_buildImportExportService)
+                {
+                    // Don't override Import-Service header, if it is found from the bnd directives.
+                    if (jar.getManifest().getMainAttributes().getValue(IMPORT_SERVICE) == null)
+                    {
+                        buildImportExportService(jar, IMPORT_SERVICE, generator.getImportService());
+                    }
+
+                    // Don't override Export-Service header, if already defined
+                    if (jar.getManifest().getMainAttributes().getValue(EXPORT_SERVICE) == null)
+                    {
+                        buildImportExportService(jar, EXPORT_SERVICE, generator.getExportService());
+                    }
+                }
+
                 copy(jar, target);
             }
         }
@@ -133,6 +170,23 @@
         }
     }
 
+    private void buildImportExportService(Jar jar, String header, Set<String> services) throws IOException
+    {
+        getLog().info("building " + header + " header with the following services: " + services);
+
+        if (services.size() > 0)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (String service : services)
+            {
+                sb.append(service);
+                sb.append(",");
+            }
+            sb.setLength(sb.length() - 1); // skip last comma
+            jar.getManifest().getMainAttributes().putValue(header, sb.toString());
+        }
+    }
+
     /**
      * Returns the target name of this maven project.
      * @return the target name of this maven project.
@@ -141,7 +195,7 @@
     {
         Build build = m_project.getBuild();
         return new File(build.getDirectory() + File.separator + build.getFinalName() + "."
-            + m_artifactExtension);
+                + m_artifactExtension);
     }
 
     /**
@@ -158,14 +212,15 @@
         {
             if (tmp.exists())
             {
-                if (! tmp.delete()) {
+                if (!tmp.delete())
+                {
                     throw new MojoExecutionException("Could not remove " + tmp);
                 }
             }
             jar.write(tmp);
             jar.close();
-            
-            if (target.exists() && ! target.delete())
+
+            if (target.exists() && !target.delete())
             {
                 throw new MojoExecutionException("Could not remove " + target);
             }
@@ -177,7 +232,8 @@
         finally
         {
             jar.close();
-            if (tmp.exists() && ! tmp.delete()) {
+            if (tmp.exists() && !tmp.delete())
+            {
                 throw new MojoExecutionException("Could not remove " + tmp);
             }
         }
diff --git a/dependencymanager/runtime/doc/changelog.txt b/dependencymanager/runtime/doc/changelog.txt
index 7f3eb61..e52d2fb 100644
--- a/dependencymanager/runtime/doc/changelog.txt
+++ b/dependencymanager/runtime/doc/changelog.txt
@@ -6,6 +6,8 @@
 ** Improvement
     * Removed root changelog.txt
     * [FELIX-2954 ] - annotated component factory does not allow to provide a component instance explicitly
+    * [FELIX-2966] - Annotations should automatically generate Import-Service/Export-Service headers
+    * [FELIX-2965] - Annotations should allow to enable or disable auto-configuration mode.
 
 Initial Release 3.0.0
 ---------------------
diff --git a/dependencymanager/runtime/pom.xml b/dependencymanager/runtime/pom.xml
index 3dbe065..ffe4a27 100644
--- a/dependencymanager/runtime/pom.xml
+++ b/dependencymanager/runtime/pom.xml
@@ -27,7 +27,7 @@
     </properties>
     <name>Apache Felix Dependency Manager Runtime</name>
     <artifactId>org.apache.felix.dependencymanager.runtime</artifactId>
-    <version>3.0.1-SNAPSHOT</version>
+    <version>3.1.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
     <dependencies>
         <dependency>
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
index 5c6d453..2127c8e 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
@@ -18,12 +18,16 @@
  */
 package org.apache.felix.dm.runtime;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
 import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
 import org.apache.felix.dm.Dependency;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 
 /**
  * Base class for all kind of DM component builders (for Component, Aspect, Adapters ...).
@@ -49,18 +53,51 @@
     /**
      * Sets common Service parameters, if provided from our Component descriptor
      */
-    protected void setCommonServiceParams(Component service, MetaData serviceMetaData)
+    protected void setCommonServiceParams(Component c, MetaData srvMeta)
         throws Exception
     {
-        String init = serviceMetaData.getString(Params.init, null);
-        String start = serviceMetaData.getString(Params.start, null);
-        String stop = serviceMetaData.getString(Params.stop, null);
-        String destroy = serviceMetaData.getString(Params.destroy, null);
-        service.setCallbacks(init, start, stop, destroy);
-        String composition = serviceMetaData.getString(Params.composition, null);
-        if (composition != null)
+        // Set auto configured component fields.
+        DependencyManager dm = c.getDependencyManager();
+        boolean autoConfigureComponents =
+                "true".equals(dm.getBundleContext().getProperty(Activator.CONF_ENABLE_AUTOCONFIG));
+
+        if (!autoConfigureComponents)
         {
-            service.setComposition(composition);
+            c.setAutoConfig(BundleContext.class, Boolean.FALSE);
+            c.setAutoConfig(ServiceRegistration.class, Boolean.FALSE);
+            c.setAutoConfig(DependencyManager.class, Boolean.FALSE);
+            c.setAutoConfig(Component.class, Boolean.FALSE);
+        }
+
+        // See if BundleContext must be auto configured.
+        String bundleContextField = srvMeta.getString(Params.bundleContextField, null);
+        if (bundleContextField != null)
+        {
+            c.setAutoConfig(BundleContext.class, bundleContextField);
+        }
+
+        // See if DependencyManager must be auto configured.
+        String dependencyManagerField = srvMeta.getString(Params.dependencyManagerField, null);
+        if (dependencyManagerField != null)
+        {
+            c.setAutoConfig(DependencyManager.class, dependencyManagerField);
+        }
+
+        // See if Component must be auto configured.
+        String componentField = srvMeta.getString(Params.componentField, null);
+        if (componentField != null)
+        {
+            c.setAutoConfig(Component.class, componentField);
+        }
+        
+        // Now, if the component has a @Started annotation, then add our component state listener,
+        // which will callback the corresponding annotated method, once the component is started.
+        String registered = srvMeta.getString(Params.registered, null);
+        String unregistered = srvMeta.getString(Params.unregistered, null);
+
+        if (registered != null || unregistered != null)
+        {
+            c.addStateListener(new RegistrationListener(registered, unregistered));
         }
     }
     
@@ -85,4 +122,68 @@
             }
         }
     }
+    
+    static class RegistrationListener implements ComponentStateListener
+    {
+        private final String m_registered;
+        private String m_unregistered;
+
+        RegistrationListener(String registered, String unregistered)
+        {
+            m_registered = registered;
+            m_unregistered = unregistered;
+        }
+        
+        public void starting(Component c)
+        {
+            // No need to invoke any callback here, since it is the ServiceLifecycleHandler
+            // that will invoke the method annotated with @Start
+        }
+
+        public void started(Component c)
+        {
+            if (m_registered != null)
+            {
+                Object instance = c.getService();
+                try
+                {
+                    InvocationUtil
+                        .invokeCallbackMethod(instance,
+                                              m_registered, 
+                                              new Class[][]  {{ ServiceRegistration.class },  {}},
+                                              new Object[][] {{ c.getServiceRegistration() }, {}});
+                }
+                catch (Throwable t)
+                {
+                    Log.instance().error("Exception caught while invoking method %s on component %s", t, m_registered, instance);
+                }
+            }
+        }
+
+        public void stopping(Component c)
+        {
+            // No need to invoke any callback here, since it is the ServiceLifecycleHandler
+            // that will invoke the method annotated with @Stop
+        }
+
+        public void stopped(Component c)
+        {
+            if (m_unregistered != null)
+            {
+                Object instance = c.getService();
+                try
+                {
+                    InvocationUtil
+                        .invokeCallbackMethod(instance,
+                                              m_unregistered, 
+                                              new Class[][]  {{}},
+                                              new Object[][] {{}});
+                }
+                catch (Throwable t)
+                {
+                    Log.instance().error("Exception caught while invoking method %s on component %s", t, m_registered, instance);
+                }
+            }
+        }
+    }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Activator.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Activator.java
index 0ee0bc3..26fe7ef 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Activator.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Activator.java
@@ -35,7 +35,17 @@
  */
 public class Activator extends DependencyActivatorBase
 {
-    private final static String CONF_LOG = "dm.runtime.log";
+    /**
+     * Name of bundle context property telling if log service is required or not.
+     * (default = false)
+     */
+    final static String CONF_LOG = "dm.runtime.log";
+    
+    /**
+     * Name of bundle context property telling if Components must be auto configured
+     * with BundleContext/ServiceRegistration etc .. (default = false) 
+     */
+    final static String CONF_ENABLE_AUTOCONFIG = "dm.runtime.autoconfig";
     
     /**
      * Initialize our DependencyManager Runtime service.
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
index 2c6a9d5..3b9f807 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
@@ -64,42 +64,43 @@
             throw new IllegalArgumentException("missing added callback");
         }
         
-        Component service;
+        Component c;
         
         if (field != null)
         {
-            service = dm.createAdapterService(adapteeService, adapteeFilter, field);
+            c = dm.createAdapterService(adapteeService, adapteeFilter, field);
         }
         else
         {
             if (added != null)
             {
-                service = dm.createAdapterService(adapteeService, adapteeFilter, added, changed, removed);
+                c = dm.createAdapterService(adapteeService, adapteeFilter, added, changed, removed);
 
             }
             else
             {
-                service = dm.createAdapterService(adapteeService, adapteeFilter);
+                c = dm.createAdapterService(adapteeService, adapteeFilter);
             }
         }
         
-        service.setInterface(provides, adapterProperties);
+        setCommonServiceParams(c, srvMeta);
+        c.setInterface(provides, adapterProperties);
         
         String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
         if (factoryMethod == null)
         {
-            service.setImplementation(adapterImplClass);
+            c.setImplementation(adapterImplClass);
         } 
         else
         {
-            service.setFactory(adapterImplClass, factoryMethod);
+            c.setFactory(adapterImplClass, factoryMethod);
         }
-        service.setComposition(srvMeta.getString(Params.composition, null));
-        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
+        c.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
         // The dependencies will be plugged by our lifecycle handler.
-        service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+        c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         // Adds dependencies (except named dependencies, which are managed by the lifecycle handler).
-        addUnamedDependencies(b, dm, service, srvMeta, depsMeta);
-        dm.add(service);
+        addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
+        dm.add(c);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
index f73099a..de4520b 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AspectServiceBuilder.java
@@ -69,47 +69,45 @@
             throw new IllegalArgumentException("missing added callback");
         }
 
-        Component service;
+        Component c;
         if (field != null)
         {
-            service =
-                    dm.createAspectService(serviceInterface, serviceFilter, ranking, field)
-                            .setServiceProperties(aspectProperties);
+            c = dm.createAspectService(serviceInterface, serviceFilter, ranking, field)
+                  .setServiceProperties(aspectProperties);
         } 
         else
         {
             if (added != null)
             {
-                service =
-                    dm.createAspectService(serviceInterface, serviceFilter, ranking, added, changed, removed)
-                        .setServiceProperties(aspectProperties);
+                c = dm.createAspectService(serviceInterface, serviceFilter, ranking, added, changed, removed)
+                      .setServiceProperties(aspectProperties);
             } 
             else
             {
-                service =
-                    dm.createAspectService(serviceInterface, serviceFilter, ranking)
-                        .setServiceProperties(aspectProperties);
+                c = dm.createAspectService(serviceInterface, serviceFilter, ranking)
+                      .setServiceProperties(aspectProperties);
             }
  
         }
         
+        setCommonServiceParams(c, srvMeta);
         String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
         if (factoryMethod == null)
         {
-            service.setImplementation(implClass);
+            c.setImplementation(implClass);
         }
         else
         {
-            service.setFactory(implClass, factoryMethod);
+            c.setFactory(implClass, factoryMethod);
         }
 
-        service.setComposition(srvMeta.getString(Params.composition, null));
-        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
+        c.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
         // The dependencies will be plugged by our lifecycle handler.
-        service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+        c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         // Adds dependencies (except named dependencies, which are managed by the lifecycle
         // handler).
-        addUnamedDependencies(b, dm, service, srvMeta, depsMeta);
-        dm.add(service);
+        addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
+        dm.add(c);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
index a093c01..94f8e62 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
@@ -51,24 +51,25 @@
         String[] provides = srvMeta.getStrings(Params.provides, null);
         Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
         boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
-        Component srv = dm.createBundleAdapterService(stateMask, filter, propagate);
-        srv.setInterface(provides, properties);
+        Component c = dm.createBundleAdapterService(stateMask, filter, propagate);
+        c.setInterface(provides, properties);
         String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
         if (factoryMethod == null)
         {
-            srv.setImplementation(adapterImplClass);
+            c.setImplementation(adapterImplClass);
         } 
         else
         {
-            srv.setFactory(adapterImplClass, factoryMethod);
+            c.setFactory(adapterImplClass, factoryMethod);
         }
 
-        srv.setComposition(srvMeta.getString(Params.composition, null));
-        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        setCommonServiceParams(c, srvMeta);
+        c.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
         // The dependencies will be plugged by our lifecycle handler.
-        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+        c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         // Adds dependencies (except named dependencies, which are managed by the lifecycle handler).
-        addUnamedDependencies(b, dm, srv, srvMeta, depsMeta);
-        dm.add(srv);
+        addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
+        dm.add(c);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentBuilder.java
index 9068005..aa0d60f 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ComponentBuilder.java
@@ -26,6 +26,8 @@
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 
 /**
  * Builds a DependencyManager Component.
@@ -47,10 +49,13 @@
     public void build(MetaData srvMeta, List<MetaData> depsMeta, Bundle b, DependencyManager dm)
         throws Exception
     {
-        Component service = dm.createComponent();
+        Component c = dm.createComponent();
         String factory = srvMeta.getString(Params.factorySet, null);
 
-        // Check if we must provide a Set Factory.
+        // Setup Component auto config fields
+        setCommonServiceParams(c, srvMeta);
+        
+        // Check if we must provide a Component factory set.
         if (factory == null)
         {
             Log.instance().info("ComponentBuilder: building service %s with dependencies %s",
@@ -62,26 +67,26 @@
             String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
             if (factoryMethod == null)
             {
-                service.setImplementation(b.loadClass(impl));
+                c.setImplementation(b.loadClass(impl));
             }
             else
             {
-                service.setFactory(b.loadClass(impl), factoryMethod);
+                c.setFactory(b.loadClass(impl), factoryMethod);
             }
-            service.setComposition(composition);
+            c.setComposition(composition);
 
             // Adds dependencies (except named dependencies, which are managed by the lifecycle
             // handler).
-            addUnamedDependencies(b, dm, service, srvMeta, depsMeta);
+            addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
             // Creates a ServiceHandler, which will filter all service lifecycle callbacks.
             ServiceLifecycleHandler lfcleHandler =
-                    new ServiceLifecycleHandler(service, b, dm, srvMeta, depsMeta);
-            service.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+                    new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
+            c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
 
             // Set the provided services
             Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
             String[] services = srvMeta.getStrings(Params.provides, null);
-            service.setInterface(services, properties);
+            c.setInterface(services, properties);
         }
         else
         {
@@ -94,13 +99,13 @@
             // This Set will act as a factory and another component may registers some
             // service configurations into it in order to fire some service instantiations.
             FactorySet factorySet = new FactorySet(b, srvMeta, depsMeta);
-            service.setImplementation(factorySet);
-            service.setCallbacks(null, "start", "stop", null);
+            c.setImplementation(factorySet);
+            c.setCallbacks(null, "start", "stop", null);
             Hashtable<String, String> props = new Hashtable<String, String>();
             props.put(DM_FACTORY_NAME, factory);
-            service.setInterface(Set.class.getName(), props);
+            c.setInterface(Set.class.getName(), props);
         }
 
-        dm.add(service);
+        dm.add(c);
     }
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
index 2576c75..0f4eb09 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
@@ -51,23 +51,24 @@
         String[] provides = srvMeta.getStrings(Params.provides, null);
         Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
         boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
-        Component srv = dm.createFactoryConfigurationAdapterService(factoryPid, updated, propagate);
-        srv.setInterface(provides, properties);
+        Component c = dm.createFactoryConfigurationAdapterService(factoryPid, updated, propagate);
+        c.setInterface(provides, properties);
         String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
         if (factoryMethod == null)
         {
-            srv.setImplementation(implClass);
+            c.setImplementation(implClass);
         } 
         else
         {
-            srv.setFactory(implClass, factoryMethod);
+            c.setFactory(implClass, factoryMethod);
         }
-        srv.setComposition(srvMeta.getString(Params.composition, null));
-        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        setCommonServiceParams(c, srvMeta);
+        c.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
         // The dependencies will be plugged by our lifecycle handler.
-        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+        c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         // Adds dependencies (except named dependencies, which are managed by the lifecycle handler).
-        addUnamedDependencies(b, dm, srv, srvMeta, depsMeta);
-        dm.add(srv);
+        addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
+        dm.add(c);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java
index a035c1e..8241b6d 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java
@@ -81,9 +81,9 @@
     private List<MetaData> m_depsMeta;
 
     /**
-     * The DependencyManager (injected by reflection), which is used to create Service instances.
+     * The DependencyManager which is used to create Service instances.
      */
-    private DependencyManager m_dm; // Injected
+    private DependencyManager m_dm;
 
     /**
      * This class is used to serialize concurrent method calls, and allow to leave our methods unsynchronized.
@@ -173,9 +173,10 @@
     /**
      * Our Service is starting. 
      */
-    public void start()
+    public void start(Component c)
     {
         m_active = true;
+        m_dm = c.getDependencyManager();
     }
 
     /**
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java
index 5cee9d6..7f0637f 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java
@@ -57,5 +57,10 @@
     name,
     field,
     starter,
-    stopper
+    stopper, 
+    bundleContextField, 
+    dependencyManagerField, 
+    componentField,
+    registered, 
+    unregistered
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
index 2e99dd2..7174396 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
@@ -51,23 +51,24 @@
         Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
         boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
         String changed = srvMeta.getString(Params.changed, null /* no change callback if not specified explicitly */);
-        Component srv = dm.createResourceAdapterService(filter, propagate, null, changed);
-        srv.setInterface(provides, properties);
+        Component c = dm.createResourceAdapterService(filter, propagate, null, changed);
+        c.setInterface(provides, properties);
         String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
         if (factoryMethod == null)
         {
-            srv.setImplementation(implClass);
+            c.setImplementation(implClass);
         } 
         else
         {
-            srv.setFactory(implClass, factoryMethod);
+            c.setFactory(implClass, factoryMethod);
         }
-        srv.setComposition(srvMeta.getString(Params.composition, null));
-        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(srv, b, dm, srvMeta, depsMeta);
+        setCommonServiceParams(c, srvMeta);
+        c.setComposition(srvMeta.getString(Params.composition, null));
+        ServiceLifecycleHandler lfcleHandler = new ServiceLifecycleHandler(c, b, dm, srvMeta, depsMeta);
         // The dependencies will be plugged by our lifecycle handler.
-        srv.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
+        c.setCallbacks(lfcleHandler, "init", "start", "stop", "destroy");
         // Adds dependencies (except named dependencies, which are managed by the lifecycle handler).
-        addUnamedDependencies(b, dm, srv, srvMeta, depsMeta);
-        dm.add(srv);
+        addUnamedDependencies(b, dm, c, srvMeta, depsMeta);
+        dm.add(c);
     }    
 }
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
index b25485f..90ff707 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
@@ -332,17 +332,16 @@
     /**
      * Invoke a callback on an Object instance.
      */
-    private Object invokeMethod(Object serviceInstance, String method, DependencyManager dm, Component service)
+    private Object invokeMethod(Object serviceInstance, String method, DependencyManager dm, Component c)
         throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
     {
         if (method != null)
         {
             try
             {
-                return InvocationUtil.invokeCallbackMethod(
-                                                           serviceInstance, method,
+                return InvocationUtil.invokeCallbackMethod(serviceInstance, method,
                                                            new Class[][] { { Component.class }, {} },
-                                                           new Object[][] { { service }, {} }
+                                                           new Object[][] { { c }, {} }
                     );
             }
 
diff --git a/dependencymanager/test/pom.xml b/dependencymanager/test/pom.xml
index 3bedbb5..94d2d04 100644
--- a/dependencymanager/test/pom.xml
+++ b/dependencymanager/test/pom.xml
@@ -39,13 +39,13 @@
         <dependency>
             <groupId>${pom.groupId}</groupId>
             <artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
-            <version>3.0.1-SNAPSHOT</version>
+            <version>3.1.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>${pom.groupId}</groupId>
             <artifactId>org.apache.felix.dependencymanager.runtime</artifactId>
-            <version>3.0.1-SNAPSHOT</version>
+            <version>3.1.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/adapter/AdapterTest.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/adapter/AdapterTest.java
index ffa9053..cbddf0a 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/adapter/AdapterTest.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/adapter/AdapterTest.java
@@ -21,13 +21,16 @@
 import java.util.Hashtable;
 import java.util.Map;
 
+import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.annotation.api.AdapterService;
 import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.Property;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
 import org.apache.felix.dm.annotation.api.Stop;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
 public class AdapterTest
@@ -83,11 +86,61 @@
         @ServiceDependency(filter="(name=AdapterAutoConfig)")
         protected Sequencer m_sequencer;
 
+        // Check auto config injections
+        @Inject
+        BundleContext m_bc;
+        BundleContext m_bcNotInjected;
+        
+        @Inject
+        DependencyManager m_dm;
+        DependencyManager m_dmNotInjected;
+        
+        @Inject
+        org.apache.felix.dm.Component m_component;
+        org.apache.felix.dm.Component m_componentNotInjected;
+        
         public void run3()
         {
+            checkInjectedFields();
             m_s1.run();
             m_sequencer.step(3);
         }
+        
+        private void checkInjectedFields()
+        {
+            if (m_bc == null)
+            {
+                m_sequencer.throwable(new Exception("Bundle Context not injected"));
+                return;
+            }
+            if (m_bcNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+                return;
+            }
+
+            if (m_dm == null)
+            {
+                m_sequencer.throwable(new Exception("DependencyManager not injected"));
+                return;
+            }
+            if (m_dmNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+                return;
+            }
+
+            if (m_component == null)
+            {
+                m_sequencer.throwable(new Exception("Component not injected"));
+                return;
+            }
+            if (m_componentNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("Component must not be injected"));
+                return;
+            }
+        }
     }
 
     @AdapterService(adapteeService = S1.class, 
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/aspect/AspectChainTest.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/aspect/AspectChainTest.java
index 86764e0..ee22c65 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/aspect/AspectChainTest.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/aspect/AspectChainTest.java
@@ -18,13 +18,16 @@
  */
 package org.apache.felix.dm.test.bundle.annotation.aspect;
 
+import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.annotation.api.AspectService;
 import org.apache.felix.dm.annotation.api.Component;
 import org.apache.felix.dm.annotation.api.Destroy;
 import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Stop;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
 public class AspectChainTest
@@ -67,6 +70,19 @@
         // Injected by reflection.
         private volatile ServiceInterface m_parentService;
 
+        // Check auto config injections
+        @Inject
+        BundleContext m_bc;
+        BundleContext m_bcNotInjected;
+        
+        @Inject
+        DependencyManager m_dm;
+        DependencyManager m_dmNotInjected;
+        
+        @Inject
+        org.apache.felix.dm.Component m_component;
+        org.apache.felix.dm.Component m_componentNotInjected;
+
         @Init
         void init() {
             System.out.println("ServiceAspect2.init");
@@ -79,9 +95,46 @@
         
         public void invoke(Runnable run)
         {
+            checkInjectedFields();
             m_sequencer.step(3);
             m_parentService.invoke(run);
         }
+        
+        private void checkInjectedFields()
+        {
+            if (m_bc == null)
+            {
+                m_sequencer.throwable(new Exception("Bundle Context not injected"));
+                return;
+            }
+            if (m_bcNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+                return;
+            }
+
+            if (m_dm == null)
+            {
+                m_sequencer.throwable(new Exception("DependencyManager not injected"));
+                return;
+            }
+            if (m_dmNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+                return;
+            }
+
+            if (m_component == null)
+            {
+                m_sequencer.throwable(new Exception("Component not injected"));
+                return;
+            }
+            if (m_componentNotInjected != null)
+            {
+                m_sequencer.throwable(new Exception("Component must not be injected"));
+                return;
+            }
+        }
     }
 
     @AspectService(ranking = 30, added="add")
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/bundledependency/ServiceProvider.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/bundledependency/ServiceProvider.java
index 6c20e9a..a63111c 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/bundledependency/ServiceProvider.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/bundledependency/ServiceProvider.java
@@ -18,12 +18,15 @@
 */
 package org.apache.felix.dm.test.bundle.annotation.bundledependency;
 
+import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.annotation.api.BundleAdapterService;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.Property;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 
 /**
  * A BundleAdapter test, which adapts the dependency manager bundle to the ServiceInterface service.
@@ -42,9 +45,23 @@
     @ServiceDependency(filter = "(test=adapter)")
     Sequencer m_sequencer;
 
+    // Check auto config injections
+    @Inject
+    BundleContext m_bc;
+    BundleContext m_bcNotInjected;
+    
+    @Inject
+    DependencyManager m_dm;
+    DependencyManager m_dmNotInjected;
+    
+    @Inject
+    org.apache.felix.dm.Component m_component;
+    org.apache.felix.dm.Component m_componentNotInjected;
+
     @Start
     void start()
     {
+        checkInjectedFields();
         m_sequencer.step(1);
     }
 
@@ -58,4 +75,40 @@
         }
         m_sequencer.step(3);
     }
+    
+    private void checkInjectedFields()
+    {
+        if (m_bc == null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context not injected"));
+            return;
+        }
+        if (m_bcNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+            return;
+        }
+
+        if (m_dm == null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager not injected"));
+            return;
+        }
+        if (m_dmNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+            return;
+        }
+
+        if (m_component == null)
+        {
+            m_sequencer.throwable(new Exception("Component not injected"));
+            return;
+        }
+        if (m_componentNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Component must not be injected"));
+            return;
+        }
+    }
 }
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/factoryconfadapter/ServiceProvider.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/factoryconfadapter/ServiceProvider.java
index 88e3bc8..f593e5a 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/factoryconfadapter/ServiceProvider.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/factoryconfadapter/ServiceProvider.java
@@ -20,12 +20,16 @@
 
 import java.util.Dictionary;
 
+import org.apache.felix.dm.DependencyManager;
 import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.Registered;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
 import org.apache.felix.dm.annotation.api.Stop;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
 
 /**
  * This service is instantiated when a factory configuration is created from ConfigAdmin
@@ -38,31 +42,87 @@
     
     private volatile boolean m_started;
 
+    // Check auto config injections
+    @Inject
+    BundleContext m_bc;
+    BundleContext m_bcNotInjected;
+    
+    @Inject
+    DependencyManager m_dm;
+    DependencyManager m_dmNotInjected;
+    
+    @Inject
+    org.apache.felix.dm.Component m_component;
+    org.apache.felix.dm.Component m_componentNotInjected;
+
     // Either initial config, or an updated config
     protected void updated(Dictionary conf)
     {
         if (m_started)
         {
-            m_sequencer.step(3);
+            m_sequencer.step(4);
         }
     }
 
     @Start
     void start()
     {
+        checkInjectedFields();
         m_started = true;
         m_sequencer.step(1);
     }    
 
+    @Registered
+    void registered()
+    {
+        m_sequencer.step(3);
+    }
+    
     // The ServiceClient is invoking our service
     public void doService()
     {
-       m_sequencer.step();
+       m_sequencer.step(); /* 2 or 5 */
     }
 
     @Stop
     void stop() 
     {
-        m_sequencer.step(5);
+        m_sequencer.step(6);
+    }
+    
+    private void checkInjectedFields()
+    {
+        if (m_bc == null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context not injected"));
+            return;
+        }
+        if (m_bcNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+            return;
+        }
+
+        if (m_dm == null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager not injected"));
+            return;
+        }
+        if (m_dmNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+            return;
+        }
+
+        if (m_component == null)
+        {
+            m_sequencer.throwable(new Exception("Component not injected"));
+            return;
+        }
+        if (m_componentNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Component must not be injected"));
+            return;
+        }
     }
 }
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java
index f7982f5..45a1f46 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java
@@ -30,6 +30,7 @@
 import org.apache.felix.dm.annotation.api.Component;
 import org.apache.felix.dm.annotation.api.Destroy;
 import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.LifecycleController;
 import org.apache.felix.dm.annotation.api.Property;
 import org.apache.felix.dm.annotation.api.ResourceAdapterService;
@@ -89,6 +90,7 @@
     @Component
     public static class ResourceProvider
     {
+        @Inject
         private volatile BundleContext m_context;
         private final Map m_handlers = new HashMap();
         private URL[] m_resources;
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ResourceProvider.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ResourceProvider.java
index 50495ef..471ab30 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ResourceProvider.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ResourceProvider.java
@@ -29,6 +29,7 @@
 import org.apache.felix.dm.ResourceUtil;
 import org.apache.felix.dm.annotation.api.Component;
 import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
@@ -40,6 +41,7 @@
 @Component
 public class ResourceProvider
 {
+    @Inject
     private volatile BundleContext m_context;
     private final Map m_handlers = new HashMap();
     private URL[] m_resources;
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ServiceProvider.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ServiceProvider.java
index a844981..74db944 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ServiceProvider.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/resource/ServiceProvider.java
@@ -22,10 +22,13 @@
 
 import junit.framework.Assert;
 
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.Property;
 import org.apache.felix.dm.annotation.api.ResourceAdapterService;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
 
 /**
  * Our ServiceInterface provider, which service is activated by a ResourceAdapter.
@@ -42,10 +45,60 @@
     @ServiceDependency(filter="(test=adapter)")
     Sequencer m_sequencer;
     
+    // Check auto config injections
+    @Inject
+    BundleContext m_bc;
+    BundleContext m_bcNotInjected;
+    
+    @Inject
+    DependencyManager m_dm;
+    DependencyManager m_dmNotInjected;
+    
+    @Inject
+    org.apache.felix.dm.Component m_component;
+    org.apache.felix.dm.Component m_componentNotInjected;
+
     public void run()
     {
+        checkInjectedFields();
         Assert.assertNotNull("Resource has not been injected in the adapter", m_resource);
         Assert.assertEquals("ServiceProvider did not get expected resource", "file://localhost/path/to/test1.txt", m_resource.toString());
         m_sequencer.step(2);
     }
+    
+    private void checkInjectedFields()
+    {
+        if (m_bc == null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context not injected"));
+            return;
+        }
+        if (m_bcNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+            return;
+        }
+
+        if (m_dm == null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager not injected"));
+            return;
+        }
+        if (m_dmNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+            return;
+        }
+
+        if (m_component == null)
+        {
+            m_sequencer.throwable(new Exception("Component not injected"));
+            return;
+        }
+        if (m_componentNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Component must not be injected"));
+            return;
+        }
+    }
 }
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/sequencer/Sequencer.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/sequencer/Sequencer.java
index 3eff238..a4723e9 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/sequencer/Sequencer.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/sequencer/Sequencer.java
@@ -40,4 +40,10 @@
      * @param timeout max milliseconds to wait.
      */
     void waitForStep(int step, int timeout);
+    
+    /**
+     *  Saves a thrown exception that occurred in a different thread. You can only save one exception
+     * at a time this way.
+     */
+    void throwable(Throwable throwable);
 }
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Consumer.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Consumer.java
index b9a1fa6..6c5a39c 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Consumer.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Consumer.java
@@ -18,11 +18,14 @@
  */
 package org.apache.felix.dm.test.bundle.annotation.simple;
 
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.Component;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
 import org.apache.felix.dm.annotation.api.Stop;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
 
 /**
  * Consumes a service which is provided by the {@link Producer} class.
@@ -35,15 +38,64 @@
     
     @ServiceDependency
     Sequencer m_sequencer;
+    
+    @Inject
+    BundleContext m_bc;
+    BundleContext m_bcNotInjected;
+    
+    @Inject
+    DependencyManager m_dm;
+    DependencyManager m_dmNotInjected;
+    
+    @Inject
+    org.apache.felix.dm.Component m_component;
+    org.apache.felix.dm.Component m_componentNotInjected;
 
     @Start
     protected void start() {
-        m_sequencer.step(2);
+        checkInjectedFields();
+        m_sequencer.step(3);
         m_runnable.run();
     }
     
+    private void checkInjectedFields()
+    {
+        if (m_bc == null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context not injected"));
+            return;
+        }
+        if (m_bcNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Bundle Context must not be injected"));
+            return;
+        }
+
+        if (m_dm == null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager not injected"));
+            return;
+        }
+        if (m_dmNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("DependencyManager must not be injected"));
+            return;
+        }
+
+        if (m_component == null)
+        {
+            m_sequencer.throwable(new Exception("Component not injected"));
+            return;
+        }
+        if (m_componentNotInjected != null)
+        {
+            m_sequencer.throwable(new Exception("Component must not be injected"));
+            return;
+        }
+    }
+
     @Stop
     protected void stop() {
-        m_sequencer.step(4);
+        m_sequencer.step(6);
     }
 }
diff --git a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Producer.java b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Producer.java
index 6367c1e..98a7386 100644
--- a/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Producer.java
+++ b/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/simple/Producer.java
@@ -19,32 +19,79 @@
 package org.apache.felix.dm.test.bundle.annotation.simple;
 
 import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Init;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
 import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.annotation.api.Registered;
 import org.apache.felix.dm.annotation.api.Stop;
+import org.apache.felix.dm.annotation.api.Unregistered;
 import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.ServiceRegistration;
 
 /**
  * Provides a <code>Runnable</code> service, which is required by the {@link Consumer} class.
  */
-@Component
+@Component(properties={@Property(name="foo", value="bar")})
 public class Producer implements Runnable
 {
     @ServiceDependency
     Sequencer m_sequencer;
+
+    @Init
+    protected void init()
+    {
+        // Our component is initializing (at this point: all required dependencies are injected).
+        m_sequencer.step(1);  
+    }
     
     @Start
-    protected void start() {
-        m_sequencer.step(1);
+    protected void start()
+    {
+        // We are about to be registered in the OSGi registry.
+        m_sequencer.step(2);
     }
-    
-    @Stop
-    protected void stop() {
-        m_sequencer.step(5);
-    }
-    
+
     public void run()
     {
-        m_sequencer.step(3);
+        // the Consumer has been injected with our service, and is invoking our run() method.
+        m_sequencer.step(4);
+    }
+
+    @Registered
+    protected void started(ServiceRegistration sr)
+    {
+        // We are registered in the OSGi registry
+        if (sr == null)
+        {
+            m_sequencer.throwable(new Exception("ServiceRegistration is null"));
+        }
+        if (!"bar".equals(sr.getReference().getProperty("foo")))
+        {
+            m_sequencer.throwable(new Exception("Invalid Service Properties"));
+        }
+        m_sequencer.step(5);
+    }
+
+    @Stop
+    protected void stop()
+    {
+        // We are about to be unregistered from the OSGi registry, and we must stop.
+        m_sequencer.step(7);
+    }
+
+    @Unregistered
+    protected void stopped()
+    {
+        // We are unregistered from the OSGi registry.
+        m_sequencer.step(8);
+    }    
+    
+    @Destroy
+    public void destroy()
+    {
+        // Our component is shutting down.
+        m_sequencer.step(9); 
     }
 }
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AdapterAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AdapterAnnotationTest.java
index a8ca2e8..c0cdadb 100644
--- a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AdapterAnnotationTest.java
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/AdapterAnnotationTest.java
@@ -76,12 +76,13 @@
      * Check if an adapter gets injected with its adaptee in a named class field.
      */
     @Test
-    public void testAnnotatedAdapterAutoConfigField(BundleContext context)
+    public void testAnnotatedAdapterAutoConfigField(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         // Provide the Sequencer to the org.apache.felix.dm.test.bundle.annotation.adapter.AdapterTest bundle 
         m.add(makeSequencer(m, "AdapterAutoConfigField"));
         m_ensure.waitForStep(3, 10000);
+        m_ensure.ensure();
     }
     
     /**
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
index 48f133b..a90b788 100644
--- 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
@@ -113,4 +113,9 @@
     {
         m_ensure.waitForStep(nr, timeout);
     }
+
+    public void throwable(Throwable throwable)
+    {
+        m_ensure.throwable(throwable);
+    }
 }
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
index ab2fdaa..882666d 100644
--- 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
@@ -61,7 +61,7 @@
     }
 
     @Test
-    public void testAspectChain(BundleContext context)
+    public void testAspectChain(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         // Activate service consumer
@@ -87,5 +87,6 @@
         m.remove(spSequencer);
         // Make sure that service aspect 1 has been called in ts removed and stop callbacks 
         m_ensure.waitForStep(8, 10000);
+        m_ensure.ensure();
     }    
 }
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/BundleDependencyAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/BundleDependencyAnnotationTest.java
index 9a4b757..ca358a5 100644
--- a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/BundleDependencyAnnotationTest.java
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/BundleDependencyAnnotationTest.java
@@ -80,13 +80,15 @@
     /**
      * Tests a Bundle Adapter, which adapts the dependency manager bundle to a "ServiceInterface" service.
      * @param context
+     * @throws Throwable 
      */
     @Test
-    public void testBundleAdapterServiceAnnotation(BundleContext context)
+    public void testBundleAdapterServiceAnnotation(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         Properties props = new Properties() {{ put("test", "adapter"); }};
         m.add(m.createComponent().setImplementation(this).setInterface(Sequencer.class.getName(), props));
         m_ensure.waitForStep(3, 10000);
+        m_ensure.ensure();
     }    
 }
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryConfigurationAdapterAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryConfigurationAdapterAnnotationTest.java
index d9535d7..38d1dd4 100644
--- a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryConfigurationAdapterAnnotationTest.java
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/FactoryConfigurationAdapterAnnotationTest.java
@@ -69,7 +69,7 @@
     }
 
     @Test
-    public void testFactoryConfigurationAdapterAnnotation(BundleContext context)
+    public void testFactoryConfigurationAdapterAnnotation(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         // Provide the Sequencer to the adapter bundle service (see main/src/.../factoryconfadapter/*.java). 
@@ -89,7 +89,8 @@
             // Remove configuration.
             cf.delete();
             // Check if ServiceProvider has been stopped.
-            m_ensure.waitForStep(5, 1000);
+            m_ensure.waitForStep(6, 1000);
+            m_ensure.ensure();
         }
         catch (IOException e)
         {
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/ResourceAnnotationTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/ResourceAnnotationTest.java
index e747fcd..7d4678e 100644
--- a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/ResourceAnnotationTest.java
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/ResourceAnnotationTest.java
@@ -94,12 +94,13 @@
      * @param context
      */
     @Test
-    public void testResourceAdapterAnnotation(BundleContext context)
+    public void testResourceAdapterAnnotation(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         Properties props = new Properties() {{ put("test", "adapter"); }};
         m.add(m.createComponent().setImplementation(this).setInterface(Sequencer.class.getName(), props));
         super.stopBundle("ResourceTest", context);
         m_ensure.waitForStep(2, 10000);
+        m_ensure.ensure();
     }
 }
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
index ce74b37..8c058d0 100644
--- 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
@@ -61,7 +61,7 @@
     }
 
     @Test
-    public void testSimpleAnnotations(BundleContext context)
+    public void testSimpleAnnotations(BundleContext context) throws Throwable
     {
         DependencyManager m = new DependencyManager(context);
         // We provide ourself as a "Sequencer" service to the annotated bundles. 
@@ -71,6 +71,7 @@
         // Stop our annotation bundle.
         stopBundle("SimpleAnnotationTest", context);
         // And check if components have been deactivated orderly.
-        m_ensure.waitForStep(5, 10000);
+        m_ensure.waitForStep(9, 10000);
+        m_ensure.ensure();
     }        
 }