FELIX-258 Support Configuration Admin configuration
FELIX-259 Add support for factory components

git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@523345 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
new file mode 100644
index 0000000..0115d58
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
@@ -0,0 +1,576 @@
+/* 
+ * 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.scr;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The default ComponentManager. Objects of this class are responsible for managing
+ * implementation object's lifecycle.  
+ *
+ */
+abstract class AbstractComponentManager implements ComponentManager, ComponentInstance
+{
+    // manager has been newly created or disabled
+    static final int STATE_DISABLED = 1;
+    
+    // manager has just been enabled and is going to be activated
+    static final int STATE_ENABLED = 2;
+    
+    // manager has been enabled but not satisfied
+    static final int STATE_UNSATISFIED = 4;
+    
+    // manager is currently activating
+    static final int STATE_ACTIVATING = 8;
+    
+    // manager is now active
+    static final int STATE_ACTIVE = 16;
+
+    // manager for a delayed component has been registered (not active yet)
+    static final int STATE_REGISTERED = 32;
+    
+    // manager for a component factory has been registered
+    static final int STATE_FACTORY = 64;
+    
+	// manager is current deactivating
+    static final int STATE_DEACTIVATING = 128;
+
+    // manager has been destroyed and may not be used anymore
+    static final int STATE_DESTROYED = 256;
+    
+    // The state of this instance manager
+    private int m_state;
+
+    // The metadata
+    private ComponentMetadata m_componentMetadata;
+    
+    // The dependency managers that manage every dependency
+    private List m_dependencyManagers;
+
+    // A reference to the BundleComponentActivator
+    private BundleComponentActivator m_activator;
+
+    // The ServiceRegistration
+    private ServiceRegistration m_serviceRegistration;
+
+    /**
+     * The constructor receives both the activator and the metadata
+     * 
+     * @param activator
+     * @param metadata
+     */
+    protected AbstractComponentManager(BundleComponentActivator activator, ComponentMetadata metadata)
+    {
+        m_activator = activator;
+        m_componentMetadata = metadata;
+        
+        m_state = STATE_DISABLED;
+        m_dependencyManagers = new ArrayList();
+    }
+    
+    /**
+     * Enable this component
+     * 
+     * @return true if enabling was successful
+     */
+    public synchronized boolean enable() {
+    	
+        if (getState() == STATE_DESTROYED)
+        {
+            Activator.error( "Destroyed Component cannot be enabled", m_componentMetadata );
+            return false;
+        }
+        else if (getState() != STATE_DISABLED)
+        {
+            Activator.trace( "Component is already enabled", m_componentMetadata );
+            return true;
+        }
+        
+        Activator.trace("Enabling component", m_componentMetadata);
+    	
+    	try
+    	{
+	        // If this component has got dependencies, create dependency managers for each one of them.
+	        if (m_componentMetadata.getDependencies().size() != 0)
+	        {
+	            Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
+	
+	            while(dependencyit.hasNext())
+	            {
+	                ReferenceMetadata currentdependency = (ReferenceMetadata)dependencyit.next();
+	
+	                DependencyManager depmanager = new DependencyManager(this, currentdependency);
+	
+	                m_dependencyManagers.add(depmanager);
+	            }
+	        }
+	
+            // enter enabled state before trying to activate
+	        setState(STATE_ENABLED);
+	        
+	        activate();
+	        
+	        return true;
+    	}
+    	catch(Exception ex)
+    	{
+    		Activator.exception( "Failed enabled Component", m_componentMetadata, ex );
+
+            // ensure we get back to DISABLED state 
+            disable();
+
+            return false;
+    	}
+    }
+
+    /**
+     * Activate this Instance manager.
+     * 
+     * 112.5.6 Activating a component configuration consists of the following steps
+     *   1. Load the component implementation class
+     *   2. Create the component instance and component context
+     *   3. Bind the target services
+     *   4. Call the activate method, if present
+     *   [5. Register provided services]
+     */
+     synchronized void activate()
+     {
+         // CONCURRENCY NOTE: This method is called either by the enable()
+         //     method or by the dependency managers or the reconfigure() method
+         if ( (getState() & (STATE_ENABLED|STATE_UNSATISFIED)) == 0)
+         {
+             // This state can only be entered from the ENABLED (in the enable()
+             // method) or UNSATISFIED (missing references) states
+             return;
+         }
+
+         // go to the activating state
+         setState(STATE_ACTIVATING);
+
+         // Before creating the implementation object, we are going to
+         // test if all the mandatory dependencies are satisfied
+         Iterator it = m_dependencyManagers.iterator();
+         while (it.hasNext())
+         {
+             DependencyManager dm = (DependencyManager)it.next();
+             if (!dm.isValid())
+             {
+                 // at least one dependency is not satisfied
+                 Activator.trace( "Dependency not satisfied: " + dm.getName(), m_componentMetadata );
+                 setState(STATE_UNSATISFIED);
+                 return;
+             }
+         }
+         
+         // 1. Load the component implementation class
+         // 2. Create the component instance and component context
+         // 3. Bind the target services
+         // 4. Call the activate method, if present
+         createComponent();
+         
+         // Validation occurs before the services are provided, otherwhise the
+         // service provider's service may be called by a service requester
+         // while it is still ACTIVATING
+         setState(getSatisfiedState());
+         
+         // 5. Register provided services
+         m_serviceRegistration = registerComponentService();
+     }
+
+     /**
+      * Method is called by {@link #activate()} in STATE_ACTIVATING or by
+      * {@link DelayedComponentManager#getService(Bundle, ServiceRegistration)}
+      * in STATE_REGISTERED.
+      */
+     protected abstract void createComponent();
+     
+     /**
+      * Method is called by {@link #deactivate()} in STATE_DEACTIVATING
+      *
+      */
+     protected abstract void deleteComponent();
+     
+     /**
+      * Returns the state value to set, when the component is satisfied. The
+      * return value depends on the kind of the component:
+      * <dl>
+      * <dt>Immediate</dt><dd><code>STATE_ACTIVE</code></dd>  
+      * <dt>Delayed</dt><dd><code>STATE_REGISTERED</code></dd>  
+      * <dt>Component Factory</dt><dd><code>STATE_FACTORY</code></dd>
+      * </dl>
+      *   
+      * @return
+      */
+     private int getSatisfiedState() {
+         if (m_componentMetadata.isFactory())
+         {
+             return STATE_FACTORY;
+         }
+         else if (m_componentMetadata.isImmediate())
+         {
+             return STATE_ACTIVE;
+         }
+         else
+         {
+             return STATE_REGISTERED;
+         }
+     }
+     
+     /**
+      * Returns the service object to be registered if the service element is
+      * specified.
+      * <p>
+      * Extensions of this class may overwrite this method to return a
+      * ServiceFactory to register in the case of a delayed or a service
+      * factory component. 
+      */
+     protected abstract Object getService();
+     
+
+     // 5. Register provided services
+     protected ServiceRegistration registerComponentService()
+     {
+         if ( getComponentMetadata().getServiceMetadata() != null )
+         {
+             Activator.trace( "registering services", getComponentMetadata() );
+
+             // get a copy of the component properties as service properties
+             Dictionary serviceProperties = copyTo( null, getProperties() );
+
+             return getActivator().getBundleContext().registerService(
+                 getComponentMetadata().getServiceMetadata().getProvides(), getService(), serviceProperties );
+         }
+         
+         return null;
+     }
+     
+     protected void unregisterComponentService()
+     {
+         if ( m_serviceRegistration != null )
+         {
+             m_serviceRegistration.unregister();
+             m_serviceRegistration = null;
+
+             Activator.trace( "unregistering the services", getComponentMetadata() );
+         }
+     }
+     
+    /**
+     * Reconfigures this component by deactivating and activating it. During
+     * activation the new configuration data is retrieved from the Configuration
+     * Admin Service.
+     */
+    public void reconfigure()
+    {
+        Activator.trace( "Deactivating and Activating to reconfigure", m_componentMetadata );
+        reactivate();
+    }
+    
+    /**
+     * Deactivates and activates this component instance.
+     */
+    void reactivate() {
+        deactivate();
+        Activator.trace( "Dependency Manager: RECREATING", m_componentMetadata ); 
+        activate();
+    }
+    
+    /**
+     * This method deactivates the manager, performing the following steps
+     * 
+     * [0. Remove published services from the registry]
+     * 1. Call the deactivate() method, if present
+     * 2. Unbind any bound services
+     * 3. Release references to the component instance and component context 
+    **/
+    synchronized void deactivate()
+    {
+        // CONCURRENCY NOTE: This method may be called either from application
+        // code or by the dependency managers or reconfiguration
+        if ((getState() & (STATE_ACTIVATING|STATE_ACTIVE|STATE_REGISTERED|STATE_FACTORY)) == 0)
+        {
+            // This state can only be entered from the ACTIVATING (if activation
+            // fails), ACTIVE, REGISTERED or FACTORY states
+            return;
+        }
+//        if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
+//            return;
+//        }
+
+        // start deactivation by resetting the state
+        setState( STATE_DEACTIVATING );
+        
+        // 0.- Remove published services from the registry
+        unregisterComponentService();
+
+        // 1.- Call the deactivate method, if present       
+        // 2. Unbind any bound services
+        // 3. Release references to the component instance and component context
+        deleteComponent();
+
+        //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+        // reset to state UNSATISFIED
+        setState( STATE_UNSATISFIED );
+    }
+
+    public synchronized void disable()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+        // but not by the dependency managers
+
+        // deactivate first, this does nothing if not active/registered/factory
+        deactivate();
+        
+        // close all service listeners now, they are recreated on enable
+        // Stop the dependency managers to listen to events...
+        Iterator it = m_dependencyManagers.iterator();
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            dm.close();
+        }
+        m_dependencyManagers.clear();
+
+        // we are now disabled, ready for re-enablement or complete destroyal
+        setState( STATE_DISABLED );
+    }
+    
+    /**
+     * 
+     */
+    public synchronized void dispose()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+    	// but not by the dependency managers
+
+        // disable first to clean up correctly
+        disable();
+        
+        // this component must not be used any more
+        setState( STATE_DISABLED );
+
+        // release references (except component metadata for logging purposes)
+        m_activator = null;
+        m_dependencyManagers = null;
+    }
+
+    //**********************************************************************************************************
+    
+    BundleComponentActivator getActivator() {
+        return m_activator;
+    }
+    
+    Iterator getDependencyManagers() {
+        return m_dependencyManagers.iterator();
+    }
+    
+    DependencyManager getDependencyManager( String name )
+    {
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            if ( name.equals( dm.getName() ) )
+            {
+                // only return the dm if it has service references 
+                return ( dm.size() > 0 ) ? dm : null;
+            }
+        }
+
+        // not found
+        return null;
+    }
+    
+    /**
+    * Get the object that is implementing this descriptor
+    *
+    * @return the object that implements the services
+    */
+    public abstract Object getInstance();
+    protected abstract Dictionary getProperties();
+
+    /**
+     * Copies the properties from the <code>source</code> <code>Dictionary</code>
+     * into the <code>target</code> <code>Dictionary</code>.
+     * 
+     * @param target The <code>Dictionary</code> into which to copy the
+     *      properties. If <code>null</code> a new <code>Hashtable</code> is
+     *      created.
+     * @param source The <code>Dictionary</code> providing the properties to
+     *      copy. If <code>null</code> or empty, nothing is copied.
+     *      
+     * @return The <code>target</code> is returned, which may be empty if
+     *      <code>source</code> is <code>null</code> or empty and
+     *      <code>target</code> was <code>null</code>.
+     */
+    protected Dictionary copyTo( Dictionary target, Dictionary source )
+    {
+        if ( target == null )
+        {
+            target = new Hashtable();
+        }
+
+        if ( source != null && !source.isEmpty() )
+        {
+            for ( Enumeration ce = source.keys(); ce.hasMoreElements(); )
+            {
+                Object key = ce.nextElement();
+                target.put( key, source.get( key ) );
+            }
+        }
+
+        return target;
+    }
+
+    ServiceReference getServiceReference() {
+        return ( m_serviceRegistration != null ) ? m_serviceRegistration.getReference() : null;
+    }
+    
+    /**
+     * 
+     */
+    public ComponentMetadata getComponentMetadata() {
+    	return m_componentMetadata;
+    }
+
+    int getState() {
+        return m_state;
+    }
+    
+    /**
+     * sets the state of the manager
+    **/
+    protected synchronized void setState(int newState) {
+        Activator.trace( "State transition : " + stateToString( m_state ) + " -> " + stateToString( newState ),
+            m_componentMetadata );
+    	
+        m_state = newState;
+    }
+
+    private String stateToString(int state) {
+        switch (state) {
+            case STATE_DESTROYED:
+                return "Destroyed";
+            case STATE_DISABLED:
+                return "Disabled";
+            case STATE_ENABLED:
+                return "Enabled";
+            case STATE_UNSATISFIED:
+                return "Unsatisfied";
+            case STATE_ACTIVATING:
+                return "Activating";
+            case STATE_ACTIVE:
+                return "Active";
+            case STATE_REGISTERED:
+                return "Registered";
+            case STATE_FACTORY:
+                return "Factory";
+            case STATE_DEACTIVATING:
+                return "Deactivating";
+            default:
+                return String.valueOf(state);
+        }
+    }
+    /**
+     * Finds the named public or protected method in the given class or any
+     * super class. If such a method is found, its accessibility is enfored by
+     * calling the <code>Method.setAccessible</code> method if required and
+     * the method is returned. Enforcing accessibility is required to support
+     * invocation of protected methods.
+     * 
+     * @param clazz The <code>Class</code> which provides the method.
+     * @param name The name of the method.
+     * @param parameterTypes The parameters to the method. Passing
+     *      <code>null</code> is equivalent to using an empty array.
+     *      
+     * @return The named method with enforced accessibility
+     * 
+     * @throws NoSuchMethodException If no public or protected method with
+     *      the given name can be found in the class or any of its super classes.
+     */
+    static Method getMethod(Class clazz, String name, Class[] parameterTypes)
+        throws NoSuchMethodException 
+    {
+        // try the default mechanism first, which only yields public methods
+        try
+        {
+            return clazz.getMethod(name, parameterTypes); 
+        }
+        catch (NoSuchMethodException nsme)
+        {
+            // it is ok to not find a public method, try to find a protected now
+        }
+        
+        // now use method declarations, requiring walking up the class
+        // hierarchy manually. this algorithm also returns protected methods
+        // which is, what we need here
+        for ( ; clazz != null; clazz = clazz.getSuperclass()) 
+        {
+            try 
+            {
+                Method method = clazz.getDeclaredMethod(name, parameterTypes);
+                
+                // only accept a protected method, a public method should
+                // have been found above and neither private nor package
+                // protected methods are acceptable here
+                if (Modifier.isProtected(method.getModifiers())) {
+                    method.setAccessible(true);
+                    return method;
+                }
+            }
+            catch (NoSuchMethodException nsme)
+            {
+                // ignore for now
+            }
+        }
+        
+        // walked up the complete super class hierarchy and still not found
+        // anything, sigh ...
+        throw new NoSuchMethodException(name);
+    }
+    
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/Activator.java b/scr/src/main/java/org/apache/felix/scr/Activator.java
index 9c7114f..0eb1c94 100644
--- a/scr/src/main/java/org/apache/felix/scr/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/Activator.java
@@ -18,18 +18,28 @@
  */
 package org.apache.felix.scr;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Logger;
 
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * This activator is used to cover requirement described in section 112.8.1 @@ -27,14
  * 37,202 @@ in active bundles.
  * 
  */
-public class Activator implements BundleActivator, SynchronousBundleListener, ServiceListener
+public class Activator implements BundleActivator, SynchronousBundleListener
 {
     // name of the LogService class
     private static final String LOGSERVICE_CLASS = LogService.class.getName();
@@ -41,37 +51,20 @@
     private static boolean m_error = true;
 
     // A string containing the version number
-    private static String m_version = "1.0.0 (12012006)";
+    private static String m_version = "1.0.0 (20070320)";
 
     // this bundle's context
     private BundleContext m_context;
     
     // the log service to log messages to
-    private static /* TODO: not very good, is it ? */ LogService m_logService;
+    private static ServiceTracker m_logService;
     
     // map of BundleComponentActivator instances per Bundle indexed by Bundle symbolic
     // name
     private Map m_componentBundles;
 
-    // Static initializations based on system properties
-    static {
-        // Get system properties to see if traces or errors need to be displayed
-        String result = System.getProperty("ds.showtrace");
-        if(result != null && result.equals("true"))
-        {
-            m_trace = true;
-        }
-        result = System.getProperty("ds.showerrors");
-        if(result != null && result.equals("false"))
-        {
-            m_error = false;
-        }
-        result = System.getProperty("ds.showversion");
-        if(result != null && result.equals("true"))
-        {
-            System.out.println("[ Version = "+m_version+" ]\n");
-        }        
-    }
+    // registry of managed component
+    private ComponentRegistry m_componentRegistry;
 
     /**
      * Registers this instance as a (synchronous) bundle listener and loads the
@@ -84,15 +77,21 @@
     {
         m_context = context;
         m_componentBundles = new HashMap();
+        m_componentRegistry = new ComponentRegistry( m_context );
 
         // require the log service
-        ServiceReference logRef = context.getServiceReference(LOGSERVICE_CLASS);
-        if (logRef != null) {
-            m_logService = (LogService) context.getService(logRef);
-        }
-        context.addServiceListener(this,
-            "(" + Constants.OBJECTCLASS + "=" + LOGSERVICE_CLASS + ")");
+        m_logService = new ServiceTracker(context, LOGSERVICE_CLASS, null);
+        m_logService.open();
         
+        // configure logging from context properties
+        m_trace = "true".equalsIgnoreCase( context.getProperty( "ds.showtrace" ) );
+        m_error = !"false".equalsIgnoreCase( context.getProperty( "ds.showerrors" ) );
+        if ( "true".equalsIgnoreCase( context.getProperty( "ds.showversion" ) ) )
+        {
+            trace( context.getBundle().getSymbolicName() + "[ Version = "
+                + context.getBundle().getHeaders().get( Constants.BUNDLE_VERSION ) + " ]", null );
+        }
+
         // register for bundle updates
         context.addBundleListener(this);
 
@@ -115,6 +114,9 @@
 
         // 112.8.2 dispose off all active components
         disposeAllComponents();
+
+        // dispose off the component registry
+        m_componentRegistry.dispose();
     }
 
     // ---------- BundleListener Interface -------------------------------------
@@ -139,23 +141,7 @@
         }
     }
 
-    //---------- ServiceListener ----------------------------------------------
-
-    // TODO:
-    public void serviceChanged(ServiceEvent event)
-    {
-        if (event.getType() == ServiceEvent.REGISTERED)
-        {
-            m_logService = (LogService) m_context.getService(event.getServiceReference());
-        }
-        else if (event.getType() == ServiceEvent.UNREGISTERING)
-        {
-            m_logService = null;
-            m_context.ungetService(event.getServiceReference());
-        }
-    }
-    
-    // ---------- Component Management -----------------------------------------
+    //---------- Component Management -----------------------------------------
 
     // Loads the components of all bundles currently active.
     private void loadAllComponents(BundleContext context)
@@ -192,14 +178,13 @@
         BundleContext context = getBundleContext(bundle);
         if (context == null)
         {
-            error("Cannot get BundleContext of bundle "
-                + bundle.getSymbolicName());
+            error( "Cannot get BundleContext of bundle " + bundle.getSymbolicName(), null );
             return;
         }
 
         try
         {
-            BundleComponentActivator ga = new BundleComponentActivator(context);
+            BundleComponentActivator ga = new BundleComponentActivator( m_componentRegistry, context );
             m_componentBundles.put(bundle.getSymbolicName(), ga);
         }
         catch (Exception e)
@@ -267,15 +252,21 @@
      */
     private BundleContext getBundleContext(Bundle bundle)
     {
-        for (Class clazz = bundle.getClass(); clazz != null; clazz = clazz.getSuperclass())
+//        try {
+//            return bundle.getBundleContext();
+//        } catch (Throwable t) {
+//            // don't care, might be that the implementation is not yet updated
+//            // to OSGi Rev 4.1
+//        }
+        
+        BundleContext context = null;
+        for (Class clazz = bundle.getClass(); context == null && clazz != null; clazz = clazz.getSuperclass())
         {
             try
             {
-                Method m = clazz.getDeclaredMethod("getContext", null);
-                if (m.getReturnType().equals(BundleContext.class))
-                {
-                    m.setAccessible(true);
-                    return (BundleContext) m.invoke(bundle, null);
+                context = getBundleContext( clazz, bundle, "getBundleContext" );
+                if (context == null) {
+                    context = getBundleContext( clazz, bundle, "getContext" );
                 }
             }
             catch (NoSuchMethodException nsme)
@@ -289,10 +280,23 @@
             }
         }
 
-        // fall back to nothing
-        return null;
+        // return what we found
+        return context;
     }
     
+    private BundleContext getBundleContext( Class clazz, Bundle bundle, String methodName )
+        throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
+    {
+        Method m = clazz.getDeclaredMethod( methodName, null );
+        if ( m.getReturnType().equals( BundleContext.class ) )
+        {
+            m.setAccessible( true );
+            return ( BundleContext ) m.invoke( bundle, null );
+        }
+        
+        // method exists but has wrong return type
+        return null;
+    }
     
     /**
      * Method to display traces
@@ -310,7 +314,7 @@
             }
             msg.append(message);
 
-            LogService log = m_logService;
+            LogService log = (LogService) m_logService.getService();
             if (log == null)
             {
                 System.out.println(msg);
@@ -326,14 +330,19 @@
      * Method to display errors
      *
      * @param message a string to be displayed
+     * @param metadata optional metadata providing more information to log
      **/
-    static void error(String message)
+    static void error(String message, ComponentMetadata metadata)
     {
         if(m_error)
         {
-            StringBuffer msg = new StringBuffer("### ").append(message);
+            StringBuffer msg = new StringBuffer("### ");
+            if(metadata != null) {
+                msg.append("[").append(metadata.getName()).append("] ");
+            }
+            msg.append(message);
 
-            LogService log = m_logService;
+            LogService log = (LogService) m_logService.getService();
             if (log == null)
             {
                 System.err.println(msg);
@@ -361,7 +370,7 @@
              msg.append("Exception with component : ");
              msg.append(message).append(" ---");
              
-             LogService log = m_logService;
+             LogService log = (LogService) m_logService.getService();
              if (log == null)
              {
                  System.err.println(msg);
diff --git a/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
index 681f1c5..ac8c9cb 100644
--- a/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
@@ -24,15 +24,21 @@
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 
+import javax.naming.ConfigurationException;
+
 import org.apache.felix.scr.parser.KXml2SAXParser;
 import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentException;
+import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * The BundleComponentActivator is helper class to load and unload Components of
@@ -41,27 +47,41 @@
  */
 class BundleComponentActivator
 {	
-	// The bundle context
+    // global component registration
+    private ComponentRegistry m_componentRegistry;
+    
+	// The bundle context owning the registered component
     private BundleContext m_context = null;
     
     // This is a list of component instance managers that belong to a particular bundle
     private List m_managers = new ArrayList();
 
-    // Global Registry of component names
-    private static Set m_componentNames = new HashSet();
+    // The Configuration Admin tracker providing configuration for components
+    private ServiceTracker m_configurationAdmin;
 
     /**
      * Called upon starting of the bundle. This method invokes initialize() which
      * parses the metadata and creates the instance managers
      *
-     * @param   context  The bundle context passed by the framework
-     * @exception   Exception any exception thrown from initialize
+     * @param componentRegistry The <code>ComponentRegistry</code> used to
+     *      register components with to ensure uniqueness of component names
+     *      and to ensure configuration updates.
+     * @param   context  The bundle context owning the components
+     * 
+     * @throws ComponentException if any error occurrs initializing this class
      */
-    BundleComponentActivator(BundleContext context) throws ComponentException
+    BundleComponentActivator(ComponentRegistry componentRegistry, BundleContext context) throws ComponentException
     {
+        // The global "Component" registry
+        this.m_componentRegistry = componentRegistry;
+        
     	// Stores the context
         m_context = context;
         
+        // have the Configuration Admin Service handy (if available)
+        m_configurationAdmin = new ServiceTracker(context, ConfigurationAdmin.class.getName(), null);
+        m_configurationAdmin.open();
+        
         // Get the Metadata-Location value from the manifest
         String descriptorLocations =
             (String) m_context.getBundle().getHeaders().get("Service-Component");
@@ -95,12 +115,13 @@
             {
                 // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
                 // fragments, SCR must log an error message with the Log Service, if present, and continue.
-                Activator.error("Component descriptor entry '" + descriptorLocation + "' not found");
+                Activator.error( "Component descriptor entry '" + descriptorLocation + "' not found", null );
                 continue;
             }
 
+            InputStream stream = null;
 			try {
-				InputStream stream = descriptorURL.openStream();
+				stream = descriptorURL.openStream();
 
 				BufferedReader in = new BufferedReader(new InputStreamReader(stream)); 
 	            XmlHandler handler = new XmlHandler(); 
@@ -121,16 +142,23 @@
     		            validate(metadata);
     		        	
     	                // Request creation of the component manager
-    	                ComponentManager manager = ManagerFactory.createManager(this,metadata);
+    	                ComponentManager manager;
+                        
+                        if (metadata.isFactory()) {
+                            // 112.2.4 SCR must register a Component Factory service on behalf ot the component
+                            // as soon as the component factory is satisfied
+                            manager = new ComponentFactoryImpl(this, metadata, m_componentRegistry);
+                        } else {
+                            manager = ManagerFactory.createManager( this, metadata, m_componentRegistry
+                            .createComponentId() );
+                        }
                 		
-                		if(metadata.isFactory())
+                        // register the component after validation
+                        m_componentRegistry.registerComponent( metadata.getName(), manager );
+                        
+                        // enable the component
+                		if(metadata.isEnabled())
                         {
-                			// 112.2.4 SCR must register a Component Factory service on behalf ot the component
-                			// as soon as the component factory is satisfied
-                		}
-                		else if(metadata.isEnabled())
-                        {
-		                	// enable the component
 		                	manager.enable();
 		                }
 
@@ -144,9 +172,6 @@
                         Activator.exception("Cannot register Component", metadata, e);
 					} 
 		        }
-		        
-		        stream.close();
-
 			}
 			catch ( IOException ex )
             {
@@ -161,6 +186,19 @@
                 Activator.exception("General problem with descriptor entry '"
                     + descriptorLocation + "'", null, ex);
 			}
+            finally
+            {
+                if ( stream != null )
+                {
+                    try
+                    {
+                        stream.close();
+                    }
+                    catch ( IOException ignore )
+                    {
+                    }
+                }
+            }
 		}
     }
 
@@ -193,11 +231,16 @@
             }
             finally
             {
-            	m_componentNames.remove(manager.getComponentMetadata().getName());
+                m_componentRegistry.unregisterComponent( manager.getComponentMetadata().getName() );
             }
             
         }
 
+        // close the Configuration Admin tracker
+        if (m_configurationAdmin != null) {
+            m_configurationAdmin.close();
+        }
+        
         Activator.trace("BundleComponentActivator : Bundle ["
             + m_context.getBundle().getBundleId() + "] STOPPED", null);
 
@@ -225,6 +268,16 @@
     }
 
     /**
+     * Returns the <code>ConfigurationAdmin</code> service used to retrieve
+     * configuration data for components managed by this activator or
+     * <code>null</code> if no Configuration Admin Service is available in the
+     * framework.
+     */
+    protected ConfigurationAdmin getConfigurationAdmin() {
+        return (ConfigurationAdmin) m_configurationAdmin.getService();
+    }
+    
+    /**
      * Implements the <code>ComponentContext.enableComponent(String)</code>
      * method by first finding the component(s) for the <code>name</code> and
      * then starting a thread to actually enable all components found.
@@ -255,8 +308,7 @@
                     }
                     catch (Throwable t) 
                     {
-                        Activator.exception("Cannot enable component",
-                            cm[i].getComponentMetadata(), t);
+                        Activator.exception( "Cannot enable component", cm[i].getComponentMetadata(), t );
                     }
                 }
             }
@@ -291,7 +343,7 @@
                 {
                     try
                     {
-                        cm[i].dispose();
+                        cm[i].disable();
                     }
                     catch (Throwable t)
                     {
@@ -326,7 +378,7 @@
             return (ComponentManager[]) m_managers.toArray(new ComponentManager[m_managers.size()]);
         }
         
-        if (m_componentNames.contains(name))
+        if ( m_componentRegistry.getComponent( name ) != null )
         {
             // otherwise just find it
             Iterator it = m_managers.iterator();
@@ -358,16 +410,19 @@
     void validate(ComponentMetadata component) throws ComponentException
     {
 
-    	if(m_componentNames.contains(component.getName()))
-    	{
-    		throw new ComponentException("The component name '"+component.getName()+"' has already been registered.");
-    	}
+        m_componentRegistry.checkComponentName( component.getName() );
     	
-        component.validate();
+        try
+        {
+            component.validate();
+        }
+        catch ( ComponentException ce )
+        {
+            // remove the reservation before leaving
+            m_componentRegistry.unregisterComponent( component.getName() );
+            throw ce;
+        }
 
-        // register the component after validation
-        m_componentNames.add(component.getName());
-    	
-        Activator.trace("Validated and registered component",component);
+        Activator.trace( "Validated and registered component", component );
     }
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java b/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
new file mode 100644
index 0000000..e2a022c
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
@@ -0,0 +1,157 @@
+/* 
+ * 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.scr;
+
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * Implementation for the ComponentContext interface
+ *
+ */
+class ComponentContextImpl implements ComponentContext
+{
+
+    private AbstractComponentManager m_componentManager;
+
+
+    ComponentContextImpl( AbstractComponentManager componentManager )
+    {
+        m_componentManager = componentManager;
+    }
+
+    
+    protected AbstractComponentManager getComponentManager()
+    {
+        return m_componentManager;
+    }
+
+    public Dictionary getProperties()
+    {
+        // 112.11.3.5 The Dictionary is read-only and cannot be modified
+        return new ReadOnlyDictionary( m_componentManager.getProperties() );
+    }
+
+
+    public Object locateService( String name )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        if ( dm == null )
+        {
+            return null;
+        }
+
+        ServiceReference selectedRef;
+        if ( dm.size() == 1 )
+        {
+            // short cut for single bound service
+            selectedRef = dm.getServiceReference();
+        }
+        else
+        {
+            // is it correct to assume an ordered bound services set ? 
+            int maxRanking = Integer.MIN_VALUE;
+            long minId = Long.MAX_VALUE;
+            selectedRef = null;
+
+            ServiceReference[] refs = dm.getServiceReferences();
+            for ( int i = 0; refs != null && i < refs.length; i++ )
+            {
+                ServiceReference ref = refs[i];
+                Integer rank = ( Integer ) ref.getProperty( Constants.SERVICE_RANKING );
+                int ranking = ( rank == null ) ? Integer.MIN_VALUE : rank.intValue();
+                long id = ( ( Long ) ref.getProperty( Constants.SERVICE_ID ) ).longValue();
+                if ( maxRanking < ranking || ( maxRanking == ranking && id < minId ) )
+                {
+                    maxRanking = ranking;
+                    minId = id;
+                    selectedRef = ref;
+                }
+            }
+        }
+
+        // this is not realistic, as at least one service is available
+        // whose service id is smaller than Long.MAX_VALUE, still be sure
+        if ( selectedRef == null )
+        {
+            return null;
+        }
+
+        // return the service for the selected reference
+        return dm.getService( selectedRef );
+    }
+
+
+    public Object locateService( String name, ServiceReference ref )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        return ( dm != null ) ? dm.getService( ref ) : null;
+    }
+
+
+    public Object[] locateServices( String name )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        return ( dm != null ) ? dm.getServices() : null;
+    }
+
+
+    public BundleContext getBundleContext()
+    {
+        return m_componentManager.getActivator().getBundleContext();
+    }
+
+
+    public Bundle getUsingBundle()
+    {
+        return null;
+    }
+
+
+    public ComponentInstance getComponentInstance()
+    {
+        return m_componentManager;
+    }
+
+
+    public void enableComponent( String name )
+    {
+        m_componentManager.getActivator().enableComponent( name );
+    }
+
+
+    public void disableComponent( String name )
+    {
+        m_componentManager.getActivator().disableComponent( name );
+    }
+
+
+    public ServiceReference getServiceReference()
+    {
+        return m_componentManager.getServiceReference();
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
new file mode 100644
index 0000000..8631883
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
@@ -0,0 +1,248 @@
+/* 
+ * 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.scr;
+
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The <code>ComponentFactoryImpl</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentFactoryImpl extends AbstractComponentManager implements ComponentFactory, ManagedServiceFactory
+{
+
+    // The component registry used to retrieve component IDs
+    private ComponentRegistry m_componentRegistry;
+
+    // The map of components created from Configuration objects
+    // maps PID to ComponentManager for configuration updating
+    // this map is lazily created
+    private Map m_configuredServices;
+
+    // Actually we only use the identity key stuff, but there is
+    // no IdentityHashSet and HashSet internally uses a HashMap anyway
+    private Map m_createdComponents;
+
+    ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata,
+        ComponentRegistry componentRegistry )
+    {
+        super( activator, metadata );
+        m_componentRegistry = componentRegistry;
+        m_createdComponents = new IdentityHashMap();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.osgi.service.component.ComponentFactory#newInstance(java.util.Dictionary)
+     */
+    public ComponentInstance newInstance( Dictionary dictionary )
+    {
+        return ( ComponentInstance ) createComponentManager( dictionary );
+    }
+
+
+    protected void createComponent()
+    {
+        // not component to create, newInstance must be used instead
+    }
+
+    public void reconfigure()
+    {
+        super.reconfigure();
+    }
+
+    protected void deleteComponent()
+    {
+        // nothing to delete
+    }
+
+
+    protected ServiceRegistration registerComponentService()
+    {
+        Activator.trace( "registering component factory", getComponentMetadata() );
+
+        Dictionary serviceProperties = getProperties();
+        return getActivator().getBundleContext().registerService( new String[]
+            { ComponentFactory.class.getName(), ManagedServiceFactory.class.getName() }, getService(),
+            serviceProperties );
+    }
+
+
+    public Object getInstance()
+    {
+        // this does not return the component instance actually
+        return null;
+    }
+
+
+    protected Dictionary getProperties()
+    {
+        Dictionary props = new Hashtable();
+        
+        // 112.5.5 The Component Factory service must register with the following properties
+        props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
+        props.put( ComponentConstants.COMPONENT_FACTORY, getComponentMetadata().getFactoryIdentifier() );
+        
+        // also register with the factory PID
+        props.put( Constants.SERVICE_PID, getComponentMetadata().getName() );
+        
+        return props;
+    }
+
+
+    protected Object getService()
+    {
+        return this;
+    }
+
+
+    //---------- ManagedServiceFactory interface ------------------------------
+
+    public void updated( String pid, Dictionary configuration )
+    {
+        ComponentManager cm;
+        if ( m_configuredServices != null )
+        {
+            cm = ( ComponentManager ) m_configuredServices.get( pid );
+        }
+        else
+        {
+            m_configuredServices = new HashMap();
+            cm = null;
+        }
+
+        if ( cm == null )
+        {
+            // create a new instance with the current configuration
+            cm = createComponentManager( configuration );
+
+            // keep a reference for future updates
+            m_configuredServices.put( pid, cm );
+        }
+        else
+        {
+            if ( cm instanceof ImmediateComponentManager )
+            {
+                // inject current configuration before cycling
+                ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+            }
+
+            // reconfigure the component
+            cm.reconfigure();
+        }
+    }
+
+
+    public void deleted( String pid )
+    {
+        if ( m_configuredServices != null )
+        {
+            ComponentManager cm = ( ComponentManager ) m_configuredServices.remove( pid );
+            if ( cm != null )
+            {
+                disposeComponentManager( cm );
+            }
+        }
+
+    }
+
+
+    public String getName()
+    {
+        return "Component Factory " + getComponentMetadata().getName();
+    }
+
+
+    //---------- internal -----------------------------------------------------
+
+    /**
+     * ComponentManager instances created by this method are not registered
+     * with the ComponentRegistry. Therefore, any configuration update to these
+     * components must be effected by this class !
+     */
+    private ComponentManager createComponentManager( Dictionary configuration )
+    {
+        long componentId = m_componentRegistry.createComponentId();
+        ComponentManager cm = ManagerFactory.createManager( getActivator(), getComponentMetadata(), componentId );
+
+        // add the new component to the activators instances
+        getActivator().getInstanceReferences().add( cm );
+
+        // register with the internal set of created components
+        m_createdComponents.put(cm, cm);
+        
+        // inject configuration if possible
+        if ( cm instanceof ImmediateComponentManager )
+        {
+            ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+        }
+
+        // immediately enable this ComponentManager
+        cm.enable();
+        
+        return cm;
+    }
+    
+    private void disposeComponentManager(ComponentManager cm) {
+        // remove from created components
+        m_createdComponents.remove( cm );
+        
+        // remove from activators list
+        getActivator().getInstanceReferences().remove( cm );
+        
+        // finally dispose it
+        cm.dispose();
+    }
+    
+    private class ComponentInstanceWrapper implements ComponentInstance {
+        
+        private ComponentManager m_component;
+        
+        ComponentInstanceWrapper(ComponentManager component) {
+            m_component = component;
+        }
+        
+        public Object getInstance()
+        {
+            return ((ComponentInstance) m_component).getInstance();
+        }
+        
+        public void dispose()
+        {
+            disposeComponentManager( m_component );
+        }
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentManager.java b/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
index 5f99652..c3fea75 100644
--- a/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
@@ -18,6 +18,8 @@
  */

 package org.apache.felix.scr;

 

+import java.util.Dictionary;

+

 /**

  * This interface is provided so that there can be multiple implementations of 

  * managers that are responsible for managing component's lifecycle.  

@@ -32,9 +34,21 @@
 	 */

 	public boolean enable();

 	

+    /**

+     * Reconfigure the component with configuration data newly retrieved from

+     * the Configuration Admin Service.

+     */

+    public void reconfigure();

+    

+    /**

+     * Disable the component. After disabling the component may be re-enabled

+     * by calling the {@link #enable()} method.

+     */

+    public void disable();

+    

 	/**

-	 * Dispose the component

-	 * 

+	 * Dispose the component. After disposing the component manager it must not

+     * be used anymore.

 	 */

 	public void dispose();

 

diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java b/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
deleted file mode 100644
index d5af234..0000000
--- a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
+++ /dev/null
@@ -1,1305 +0,0 @@
-/* 
- * 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.scr;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.osgi.framework.*;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.ComponentInstance;
-
-
-/**
- * The default ComponentManager. Objects of this class are responsible for managing
- * implementation object's lifecycle.  
- *
- */
-class ComponentManagerImpl implements ComponentManager, ComponentInstance
-{
-	// States of the instance manager
-	static final int INSTANCE_CREATING = 0;
-	static final int INSTANCE_CREATED = 1;
-	static final int INSTANCE_VALIDATING = 2;
-	static final int INSTANCE_VALID = 3;
-	static final int INSTANCE_INVALIDATING = 4;
-	static final int INSTANCE_INVALID = 5;
-	static final int INSTANCE_DESTROYING = 6;
-	static final int INSTANCE_DESTROYED = 7;
-		
-
-    static final String m_states[]={"CREATING","CREATED",
-    								"VALIDATING","VALID",
-    								"INVALIDATING","INVALID",
-    								"DESTROYING","DESTROYED"
-                                    };
-
-    // The state of this instance manager
-    private int m_state = INSTANCE_CREATING;
-
-    // The metadata
-    private ComponentMetadata m_componentMetadata;
-
-    // The object that implements the service and that is bound to other services
-    private Object m_implementationObject = null;
-
-    // The dependency managers that manage every dependency
-    private List m_dependencyManagers = new ArrayList();
-
-    // The ServiceRegistration
-    private ServiceRegistration m_serviceRegistration = null;
-
-    // A reference to the BundleComponentActivator
-    private BundleComponentActivator m_activator = null;
-
-    // The context that will be passed to the implementationObject
-    private ComponentContext m_componentContext = null;
-    
-    // In case of a delayed component, this holds a reference to the factory
-    private ServiceFactory m_delayedComponentServiceFactory;
-    
-    /**
-     * The constructor receives both the activator and the metadata
-     * 
-     * @param activator
-     * @param metadata
-     */
-    ComponentManagerImpl(BundleComponentActivator activator, ComponentMetadata metadata)
-    {
-    	// Store the activator reference
-        m_activator = activator;
-
-        // Store the metadata reference
-        m_componentMetadata = metadata;
-    }
-    
-    /**
-     * Enable this component
-     * 
-     * @return true if enabling was successful
-     */
-    public boolean enable() {
-    	
-        Activator.trace("Enabling component", m_componentMetadata);
-    	
-    	try
-    	{
-	        // If this component has got dependencies, create dependency managers for each one of them.
-	        if (m_componentMetadata.getDependencies().size() != 0)
-	        {
-	            Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
-	
-	            while(dependencyit.hasNext())
-	            {
-	                ReferenceMetadata currentdependency = (ReferenceMetadata)dependencyit.next();
-	
-	                DependencyManager depmanager = new DependencyManager(currentdependency);
-	
-	                m_dependencyManagers.add(depmanager);
-	
-	                // Register the dependency managers as listeners to service events so that they begin
-	                // to manage the dependency autonomously
-	                m_activator.getBundleContext().addServiceListener(depmanager,depmanager.m_dependencyMetadata.getTarget());
-	            }
-	        }
-	
-	        // TODO: create the context
-	        //m_sbcontext = new ServiceBinderContextImpl(this);
-	
-	        // Add this instance manager to the Generic activator list
-	        //m_activator.addInstanceManager(this);
-	        
-	
-	        setState(INSTANCE_CREATED);
-	        
-	        activate();
-	        
-	        return true;
-    	}
-    	catch(Exception ex)
-    	{
-    		// TODO: Log this error
-    		return false;
-    	}
-    }
-
-    /**
-    * Activate this Instance manager.
-    * 
-    * 112.5.6 Activating a component configuration consists of the following steps
-    *   1. Load the component implementation class
-    *   2. Create the component instance and component context
-    *   3. Bind the target services
-    *   4. Call the activate method, if present
-    *   [5. Register provided services]
-    */
-    synchronized private void activate()
-    {
-        // CONCURRENCY NOTE: This method is called either by the enable() method or by the dependency
-    	// managers.    	
-    	if (m_state != INSTANCE_INVALID && m_state !=INSTANCE_CREATED) {
-    		// This state can only be entered from the CREATED or INVALID states
-    		return;
-    	}
-
-        setState(INSTANCE_VALIDATING);
-
-        // Before creating the implementation object, we are going to
-        // test if all the mandatory dependencies are satisfied
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            // It is not possible to call the isValid method yet in the DependencyManagers
-            // since they have not been initialized yet, but they can't be initialized yet
-            // because the implementationObject has not been created yet.
-            // This test is necessary, because we don't want to instantiate
-            // the implementationObject if the dependency managers aren't valid.
-            DependencyManager dm = (DependencyManager)it.next();
-            if (dm.getRequiredServiceRefs() == null && dm.m_dependencyMetadata.isOptional() == false)
-            {
-                setState(INSTANCE_INVALID);
-                return;
-            }
-        }
-        
-        // 1. Load the component implementation class
-        // 2. Create the component instance and component context
-        // If the component is not immediate, this is not done at this moment
-        if( m_componentMetadata.isImmediate() == true )
-        {
-            //Activator.trace("Loading implementation class and creating instance for component '"+m_componentMetadata.getName()+"'");
-        	try
-	        {
-	        	// 112.4.4 The class is retrieved with the loadClass method of the component's bundle
-	            Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
-	            
-	            // 112.4.4 The class must be public and have a public constructor without arguments so component instances
-	            // may be created by the SCR with the newInstance method on Class
-	            m_componentContext = new ComponentContextImpl(null);
-	            m_implementationObject = c.newInstance();
-	        }
-	        catch (Exception ex)
-	        {
-	            // TODO: manage this exception when implementation object cannot be created
-	            Activator.exception("Error during instantiation", m_componentMetadata, ex);
-	            deactivate();
-	            //invalidate();
-	            return;
-	        }
-        }
-        else if ( m_componentMetadata.getServiceMetadata() != null
-            && m_componentMetadata.getServiceMetadata().isServiceFactory() )
-        {
-            // delayed component is a ServiceFactory service
-            m_delayedComponentServiceFactory = new DelayedServiceFactoryServiceFactory();
-        }
-        else
-        {
-            // delayed component is a standard service
-            m_delayedComponentServiceFactory = new DelayedComponentServiceFactory();
-        }
-        
-        // 3. Bind the target services
-        it = m_dependencyManagers.iterator();
-
-        //Activator.trace("Binding target services for component '"+m_componentMetadata.getName()+"'");
-        
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            
-            // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
-            if (dm.bind() == false)
-            {
-            	deactivate();
-                return;
-            }
-        }
-        
-        //Activator.trace("Calling activate for component '"+m_componentMetadata.getName()+"'");
-        
-        // 4. Call the activate method, if present
-	        // We need to check if we are still validating because it is possible that when we
-	        // registered the service above our thread causes an instance to become valid which
-	        // then registered a service that then generated an event that we needed that
-	        // caused validate() to be called again, thus if we are not still VALIDATING, it
-	        // means we are already VALID.
-        if ( m_componentMetadata.isImmediate() == true && m_state == INSTANCE_VALIDATING)
-        {
-            // Search for the activate method
-        	try {
-                Method activateMethod = getMethod(m_implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
-        		activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});
-        	}
-        	catch(NoSuchMethodException ex) {        		
-        	    // We can safely ignore this one
-        	    Activator.trace("activate() method not implemented", m_componentMetadata);
-        	}
-        	catch(IllegalAccessException ex) {
-        	    // TODO: Log this exception?
-        	    Activator.trace("activate() method cannot be called", m_componentMetadata);
-        	}
-        	catch(InvocationTargetException ex) {
-        	    // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
-        	    // containing the exception with the Log Service
-        	    Activator.exception("The activate method has thrown an exception", m_componentMetadata, ex.getTargetException());
-        	}
-        }
-        
-        // Validation occurs before the services are provided, otherwhise the service provider's service may be called
-        // by a service requester while it is still VALIDATING
-        setState(INSTANCE_VALID);
-        
-        // 5. Register provided services
-        if(m_componentMetadata.getServiceMetadata() != null)
-        {
-            Activator.trace("registering services", m_componentMetadata);
-
-        	if( m_componentMetadata.isImmediate() == true ) {
-	        	// In the case the component is immediate, the implementation object is registered
-	        	m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_implementationObject, m_componentMetadata.getProperties());
-	        }else {
-	        	// In the case the component is delayed, a factory is registered
-	        	m_serviceRegistration = m_activator.getBundleContext().registerService(m_componentMetadata.getServiceMetadata().getProvides(), m_delayedComponentServiceFactory, m_componentMetadata.getProperties());
-	        }
-        }
-    }
-    
-    /**
-     * This method deactivates the manager, performing the following steps
-     * 
-     * [0. Remove published services from the registry]
-     * 1. Call the deactivate() method, if present
-     * 2. Unbind any bound services
-     * 3. Release references to the component instance and component context 
-    **/
-    synchronized private void deactivate()
-    {
-    	// CONCURRENCY NOTE: This method may be called either from application code or by the dependency managers
-    	if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
-    		return;
-    	}
-
-    	// In case the instance is valid when this is called, the manager is set to an invalidating state
-        if (m_state != INSTANCE_DESTROYING)
-        {
-            setState(INSTANCE_INVALIDATING);
-        }
-    	
-        // 0.- Remove published services from the registry
-        if(m_serviceRegistration != null)
-        {
-	        m_serviceRegistration.unregister();
-	        m_serviceRegistration = null;
-
-	        Activator.trace("unregistering the services", m_componentMetadata);
-	    }
-
-        // 1.- Call the deactivate method, if present	    
-        // Search the deactivate method
-		try {
-			// It is necessary to check that the implementation Object is not null. This may happen if the component
-			// is delayed and its service was never requested.
-			if(m_implementationObject != null)
-			{
-				Method activateMethod = getMethod(m_implementationObject.getClass(), "deactivate", new Class[]{ComponentContext.class});
-				activateMethod.invoke(m_implementationObject, new Object[]{m_componentContext});				
-			}
-		}
-		catch(NoSuchMethodException ex) {
-            // We can safely ignore this one
-			Activator.trace("deactivate() method is not implemented", m_componentMetadata);
-		}
-		catch(IllegalAccessException ex) {
-			// Ignored, but should it be logged?
-			Activator.trace("deactivate() method cannot be called", m_componentMetadata);
-		}
-		catch(InvocationTargetException ex) {
-			// TODO: 112.5.12 If the deactivate method throws an exception, SCR must log an error message
-			// containing the exception with the Log Service
-			Activator.exception("The deactivate method has thrown and exception", m_componentMetadata, ex);
-		}
-
-        // 2. Unbind any bound services
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            dm.unbind();
-        }
-
-        // 3. Release references to the component instance and component context
-        m_implementationObject = null;
-        m_componentContext = null;
-        m_delayedComponentServiceFactory = null;
-
-        //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
-
-        if (m_state != INSTANCE_DESTROYING)
-        {
-            setState(INSTANCE_INVALID);
-        }
-    }
-
-    /**
-     * 
-     */
-    public synchronized void dispose()
-    {
-        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
-    	// but not by the dependency managers
-
-        // Theoretically this should never be in any state other than VALID or INVALID,
-        // because validate is called right after creation.
-        if (m_state != INSTANCE_VALID && m_state != INSTANCE_INVALID)
-        {
-            return;
-        }
-
-        boolean deactivationRequired = (m_state == INSTANCE_VALID);
-
-        setState(INSTANCE_DESTROYING);
-
-        // Stop the dependency managers to listen to events...
-        Iterator it = m_dependencyManagers.iterator();
-
-        while (it.hasNext())
-        {
-            DependencyManager dm = (DependencyManager)it.next();
-            m_activator.getBundleContext().removeServiceListener(dm);
-        }
-
-        // in case the component is disposed when it was VALID, it is necessary to deactivate it first.
-        if (deactivationRequired)
-        {
-            deactivate();
-        }
-
-        m_dependencyManagers.clear();
-
-        setState(INSTANCE_DESTROYED);
-
-        m_activator = null;
-    }
-
-    //**********************************************************************************************************
-    
-    /**
-    * Get the object that is implementing this descriptor
-    *
-    * @return the object that implements the services
-    */
-    public Object getInstance() {
-        return m_implementationObject;
-    }
-
-    /**
-     * 
-     */
-    public ComponentMetadata getComponentMetadata() {
-    	return m_componentMetadata;
-    }
-    
-    /**
-     * sets the state of the manager
-    **/
-    private synchronized void setState(int newState) {
-        Activator.trace("State transition : "+m_states[m_state]+" -> "+m_states[newState], m_componentMetadata);
-    	
-        m_state = newState;
-        
-        
-
-        if(m_state == INSTANCE_CREATED || m_state == INSTANCE_VALID || m_state == INSTANCE_INVALID || m_state == INSTANCE_DESTROYED)
-        {
-            //m_activator.fireInstanceChangeEvent(new InstanceChangeEvent(this,m_instanceMetadata,m_state));
-        }
-    }
-
-/**
- * The DependencyManager task is to listen to service events and to call the * bind/unbind methods on a given object. It is also responsible for requesting * the unregistration of a service in case a dependency is broken.
- */
-    class DependencyManager implements ServiceListener
-    {
-    	// Reference to the metadata
-        private ReferenceMetadata m_dependencyMetadata;
-
-        // The bound services <ServiceReference> 
-        private Set m_boundServicesRefs = new HashSet();
-        
-        // A flag that denotes if the dependency is satisfied at any given moment
-        private boolean m_isValid;
-        
-        // A flag that defines if the bind method receives a ServiceReference
-        private boolean m_bindUsesServiceReference = false;
-
-        /**
-         * Constructor that receives several parameters.
-         *
-         * @param   dependency  An object that contains data about the dependency
-        **/
-        private DependencyManager(ReferenceMetadata dependency) throws ClassNotFoundException, NoSuchMethodException
-        {
-            m_dependencyMetadata = dependency;
-            m_isValid = false;
-
-            //m_bindMethod = getTargetMethod(m_dependencyMetadata.getBind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
-            //m_unbindMethod = getTargetMethod(m_dependencyMetadata.getUnbind(), m_componentMetadata.getImplementationClassName(),m_dependencyMetadata.getInterface());
-        }
-
-        /**
-         * initializes a dependency. This method binds all of the service occurrences to the instance object
-         *
-         * @return true if the operation was successful, false otherwise
-        **/
-        private boolean bind()
-        {
-        	/* 
-            if(getInstance() == null)
-            {
-                return false;
-            }*/
-
-            // Get service references
-            ServiceReference refs[] = getRequiredServiceRefs();
-
-            // If no references were received, we have to check if the dependency
-            // is optional, if it is not then the dependency is invalid
-            if (refs == null && m_dependencyMetadata.isOptional() == false)
-            {
-                m_isValid = false;
-                return m_isValid;
-            }
-
-            m_isValid = true;
-
-            // refs can be null if the dependency is optional
-            if (refs != null)
-            {
-                int max = 1;
-                boolean retval = true;
-
-                if (m_dependencyMetadata.isMultiple() == true)
-                {
-                    max = refs.length;
-                }
-
-                for (int index = 0; index < max; index++)
-                {
-                    retval = invokeBindMethod(m_implementationObject, refs[index]);
-                    if(retval == false && (max == 1))
-                    {
-                        // There was an exception when calling the bind method
-                        Activator.error("Dependency Manager: Possible exception in the bind method during initialize()");
-                        m_isValid = false;
-                        //setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
-                        return m_isValid;
-                    }
-                }
-            }
-
-            return m_isValid;
-        }
-
-        /**
-         * Revoke all bindings. This method cannot throw an exception since it must try
-         * to complete all that it can
-         *
-        **/
-        private void unbind()
-        {
-            Object []allrefs = m_boundServicesRefs.toArray();
-
-            if (allrefs == null)
-                return;
-
-            for (int i = 0; i < allrefs.length; i++)
-            {
-                invokeUnbindMethod(m_implementationObject, (ServiceReference)allrefs[i]);
-            }
-        }
-
-        /**
-         *
-         * Returns an array containing the service references that are pertinent to the
-         * dependency managed by this object. This method filters out services that
-         * belong to bundles that are being (or are actually) shutdown. This is an issue
-         * since is not clearly specified in the OSGi specification if a getServiceReference
-         * call should return the services that belong to bundles that are stopping.
-         *
-         * @return an array of ServiceReferences valid in the context of this dependency
-        **/
-        private ServiceReference [] getRequiredServiceRefs()
-        {
-            try
-            {
-                ArrayList list=new ArrayList();
-                
-                ServiceReference temprefs[] = m_activator.getBundleContext().getServiceReferences(m_dependencyMetadata.getInterface(), m_dependencyMetadata.getTarget());
-
-                if (temprefs == null)
-                {
-                    return null;
-                }
-
-                for (int i = 0; i < temprefs.length; i++)
-                {
-                     if (temprefs[i].getBundle().getState() == Bundle.ACTIVE
-                            || temprefs[i].getBundle().getState() == Bundle.STARTING)
-                     {
-                         list.add(temprefs[i]);
-                     }
-                }
-
-                return (ServiceReference []) list.toArray(new ServiceReference [temprefs.length]);
-
-            }
-            catch (Exception e)
-            {
-                Activator.error("DependencyManager: exception while getting references :"+e);
-                return null;
-            }
-        }
-
-        /**
-         * Gets a bind or unbind method according to the policies described in the specification
-         *
-         * @param methodname The name of the method
-         * @param targetClass the class to which the method belongs to
-         * @param parameterClassName the name of the class of the parameter that is passed to the method
-         * @return the method or null
-         * @throws java.lang.ClassNotFoundException if the class was not found
-        **/
-        private Method getBindingMethod(String methodname, Class targetClass, String parameterClassName)
-        {
-            Method method = null;
-            
-            Class parameterClass = null;
-            
-            // 112.3.1 The method is searched for using the following priority
-            // 1. The method's parameter type is org.osgi.framework.ServiceReference
-            // 2. The method's parameter type is the type specified by the reference's interface attribute
-            // 3. The method's parameter type is assignable from the type specified by the reference's interface attribute
-            try{
-            	// Case 1
-            	
-                method = getMethod(targetClass, methodname, new Class[]{ServiceReference.class});
-               
-                m_bindUsesServiceReference = true;                
-            }
-            catch(NoSuchMethodException ex){
-            	
-            	try {
-            		// Case2
-            		
-            		m_bindUsesServiceReference = false;
-            		
-            		parameterClass = m_activator.getBundleContext().getBundle().loadClass(parameterClassName);
-            		
-	                method = getMethod(targetClass, methodname, new Class[]{parameterClass});
-            	}
-                catch(NoSuchMethodException ex2) {
-            		
-                    // Case 3
-                    method = null;
-            		
-                    // iterate on class hierarchy
-                    for ( ; method == null && targetClass != null; targetClass = targetClass.getSuperclass())
-                    {
-                        // Get all potential bind methods
-                        Method candidateBindMethods[]  = targetClass.getDeclaredMethods();
-                       
-                        // Iterate over them
-                        for(int i = 0; method == null && i < candidateBindMethods.length; i++) {
-                            Method currentMethod = candidateBindMethods[i];
-                           
-                            // Get the parameters for the current method
-                            Class[] parameters = currentMethod.getParameterTypes();
-                           
-                            // Select only the methods that receive a single parameter
-                            // and a matching name
-                            if(parameters.length == 1 && currentMethod.getName().equals(methodname)) {
-                               
-                                // Get the parameter type
-                                Class theParameter = parameters[0];
-                               
-                                // Check if the parameter type is assignable from the type specified by the reference's interface attribute
-                                if(theParameter.isAssignableFrom(parameterClass)) {
-                                    
-                                    // Final check: it must be public or protected
-                                    if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers()))
-                                    {
-                                        if (!method.isAccessible())
-                                        {
-                                            method.setAccessible(true);
-                                        }
-                                        method = currentMethod;
-                                        
-                                    }
-                                }
-                            }                           
-                        }
-                    }
-            	} 
-            	catch(ClassNotFoundException ex2) {
-            		Activator.exception("Cannot load class used as parameter "+parameterClassName,m_componentMetadata,ex2);
-            	}
-            }
-                        
-            return method;
-        }
-
-        /**
-         * Call the bind method. In case there is an exception while calling the bind method, the service
-         * is not considered to be bound to the instance object
-         *
-         * @param implementationObject The object to which the service is bound
-         * @param ref A ServiceReference with the service that will be bound to the instance object
-         * @param storeRef A boolean that indicates if the reference must be stored (this is used for the delayed components)
-         * @return true if the call was successful, false otherwise
-        **/
-        private boolean invokeBindMethod(Object implementationObject, ServiceReference ref) {
-        	// The bind method is only invoked if the implementation object is not null. This is valid
-        	// for both immediate and delayed components
-        	if(implementationObject != null) {
-        		
-		        try {
-		        	// Get the bind method
-		            Method bindMethod = getBindingMethod(m_dependencyMetadata.getBind(), implementationObject.getClass(), m_dependencyMetadata.getInterface());
-		            
-		            if(bindMethod == null){
-		            	// 112.3.1 If the method is not found , SCR must log an error
-		            	// message with the log service, if present, and ignore the method
-		            	// TODO: log error message
-		                Activator.trace("bind() method not found", m_componentMetadata);
-		            	return false;
-		            }
-		            
-		            // Get the parameter
-		            Object parameter;
-		            
-		            if(m_bindUsesServiceReference == false) {		            	 
-		            	parameter = m_activator.getBundleContext().getService(ref);
-		            }
-		            else {
-		            	parameter = ref;
-		            }
-		            	
-		            // Invoke the method
-		            bindMethod.invoke(implementationObject, new Object[] {parameter});
-		            
-		            // Store the reference
-		        	m_boundServicesRefs.add(ref);                
-		            
-		            return true;
-		        }
-		        catch(IllegalAccessException ex)
-		        {
-		        	// 112.3.1 If the method is not is not declared protected or public, SCR must log an error
-		        	// message with the log service, if present, and ignore the method
-		        	// TODO: log error message
-		        	return false;
-		        }
-		        catch(InvocationTargetException ex)
-		        {
-		        	Activator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getBind()+"()", m_componentMetadata, ex);
-		            return false;
-		        }
-        	} else if( implementationObject == null && m_componentMetadata.isImmediate() == false) {
-        		// In the case the implementation object is null and the component is delayed
-        		// then we still have to store the object that is passed to the bind methods
-        		// so that it can be used once the implementation object is created.
-        		m_boundServicesRefs.add(ref);
-        		return true;
-        	} else {
-        		// TODO: assert false : this theoretically never happens...
-        		return false;
-        	}        	
-        }
-
-        /**
-         * Call the unbind method
-         *
-         * @param implementationObject The object from which the service is unbound
-         * @param ref A service reference corresponding to the service that will be unbound
-         * @return true if the call was successful, false otherwise
-        **/
-        private boolean invokeUnbindMethod(Object implementationObject, ServiceReference ref) {
-        	// TODO: assert m_boundServices.contains(ref) == true : "DependencyManager : callUnbindMethod UNBINDING UNKNOWN SERVICE !!!!";	
-        	
-        	// The unbind method is only invoked if the implementation object is not null. This is valid
-        	// for both immediate and delayed components
-        	if ( implementationObject != null ) {
-	            try
-	            {
-	            	// TODO: me quede aqui por que el unbind method no funciona
-	                Activator.trace("getting unbind: "+m_dependencyMetadata.getUnbind(), m_componentMetadata);
-	            	Method unbindMethod = getBindingMethod(m_dependencyMetadata.getUnbind(), implementationObject.getClass(), m_dependencyMetadata.getInterface());
-	            	
-		        	// Recover the object that is bound from the map.
-		            //Object parameter = m_boundServices.get(ref);
-	        		Object parameter = null;
-	        		
-	        		if(m_bindUsesServiceReference == true) {
-	        			parameter = ref;
-	        		} else {
-	        			parameter = m_activator.getBundleContext().getService(ref);
-	        		}
-		            
-	            	if(unbindMethod == null){
-	                	// 112.3.1 If the method is not found , SCR must log an error
-	                	// message with the log service, if present, and ignore the method
-	                	// TODO: log error message
-	            	    Activator.trace("unbind() method not found", m_componentMetadata);
-	                	return false;
-	                }
-	
-	            	unbindMethod.invoke(implementationObject, new Object [] {parameter});
-	            	                
-	                m_boundServicesRefs.remove(ref);
-	                
-	                m_activator.getBundleContext().ungetService(ref);
-	                
-	                return true;
-	            }
-	            catch (IllegalAccessException ex) {
-	            	// 112.3.1 If the method is not is not declared protected or public, SCR must log an error
-	            	// message with the log service, if present, and ignore the method
-	            	// TODO: log error message
-	            	return false;
-	            }
-	            catch (InvocationTargetException ex) {
-	                Activator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbind()+"()", m_componentMetadata, ex);
-	            	return false;
-	            }
-	            
-        	} else if( implementationObject == null && m_componentMetadata.isImmediate() == false) {
-        		// In the case the implementation object is null and the component is delayed
-        		// then we still have to store the object that is passed to the bind methods
-        		// so that it can be used once the implementation object is created.
-        		m_boundServicesRefs.remove(ref);
-        		return true;
-        	} else {
-        		// TODO: assert false : this theoretically never happens...
-        		return false;
-        	}
-        }
-        
-        /**
-         * Called upon a service event. This method is responsible for calling the
-         * binding and unbinding methods and also to request the eventual unregistering
-         * of a service when a dependency breaks
-         *
-         * @param evt  The ServiceEvent
-        **/
-        public void serviceChanged(ServiceEvent evt)
-        {
-            synchronized (ComponentManagerImpl.this)
-            {
-                // If the object is being created or destroyed, we can safely ignore events.
-                if (m_state == INSTANCE_DESTROYING || m_state == INSTANCE_DESTROYED || m_state == INSTANCE_CREATING || m_state == INSTANCE_CREATED)
-                {
-                    return;
-                }
-
-                // If we are in the process of invalidating, it is not necessary to pass
-                // unregistration events, since we are unbinding everything anyway.
-                else if (m_state == INSTANCE_INVALIDATING && evt.getType() == ServiceEvent.UNREGISTERING)
-                {
-                    return;
-                }
-
-                // We do not have an entry for VALIDATING because it is reentrant.
-
-                // A service is unregistering
-                if (evt.getType() == ServiceEvent.UNREGISTERING)
-                {
-                    if (m_boundServicesRefs.contains(evt.getServiceReference()) == true)
-                    {
-                        // A static dependency is broken the instance manager will be invalidated
-                        if (m_dependencyMetadata.isStatic())
-                        {
-                            m_isValid = false;
-                            //setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
-                            try
-                            {
-                                Activator.trace("Dependency Manager: Static dependency is broken", m_componentMetadata);
-                                deactivate();
-                                Activator.trace("Dependency Manager: RECREATING", m_componentMetadata);
-                                activate();
-                            }
-                            catch(Exception ex)
-                            {
-                                Activator.exception("Exception while recreating dependency ",m_componentMetadata, ex);
-                            }
-                        }
-                        // dynamic dependency
-                        else
-                        {
-                            // Release references to the service, call unbinder method
-                            // and eventually request service unregistration
-
-                            invokeUnbindMethod(m_implementationObject, evt.getServiceReference());
-
-                            // The only thing we need to do here is check if we can reinitialize
-                            // once the bound services becomes zero. This tries to repair dynamic
-                            // 1..1 or rebind 0..1, since replacement services may be available.
-                            // In the case of aggregates, this will only invalidate them since they
-                            // can't be repaired.
-                            if (m_boundServicesRefs.size() == 0)
-                            {
-                                // try to reinitialize
-                                if (!bind())
-                                {
-                                    if (!m_dependencyMetadata.isOptional())
-                                    {
-                                        Activator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...", m_componentMetadata);
-                                        deactivate();
-                                        Activator.trace("Dependency Manager: Recreating", m_componentMetadata);
-                                        activate();
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                // A service is registering.
-                else if (evt.getType() == ServiceEvent.REGISTERED)
-                {
-                    if (m_boundServicesRefs.contains(evt.getServiceReference()) == true)
-                    {
-                        // This is a duplicate
-                        Activator.trace("DependencyManager : ignoring REGISTERED ServiceEvent (already bound)", m_componentMetadata);
-                    }
-                    else
-                    {
-                        m_isValid = true;
-                        //setStateDependency(DependencyChangeEvent.DEPENDENCY_VALID);
-
-                        // If the InstanceManager is invalid, a call to validate is made
-                        // which will fix everything.
-                        if (ComponentManagerImpl.this.m_state != INSTANCE_VALID)
-                        {
-                            activate();
-                        }
-                        // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N it never
-                        // checks for 1..1 dynamic which is done above by the validate()
-                        else if (!m_dependencyMetadata.isStatic())
-                        {
-                            // For dependency that are aggregates, always bind the service
-                            // Otherwise only bind if bind services is zero, which captures the 0..1 case
-                            if (m_dependencyMetadata.isMultiple() || m_boundServicesRefs.size() == 0)
-                            {
-                                invokeBindMethod(m_implementationObject, evt.getServiceReference());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Implementation for the ComponentContext interface
-     *
-     */
-    class ComponentContextImpl implements ComponentContext {
-
-        private Bundle m_usingBundle;
-
-        ComponentContextImpl(Bundle usingBundle)
-        {
-            m_usingBundle = usingBundle;
-        }
-
-    	public Dictionary getProperties() {
-    		//TODO: 112.11.3.5 The Dictionary is read-only and cannot be modified
-    		return m_componentMetadata.getProperties();
-    	}
-
-        public Object locateService(String name) {
-            DependencyManager dm = getDependencyManager(name);
-            if (dm == null || dm.m_boundServicesRefs.isEmpty())
-            {
-                return null;
-            }
-            
-            ServiceReference selectedRef;
-            if (dm.m_boundServicesRefs.size() == 1)
-            {
-                // short cut for single bound service
-                selectedRef = (ServiceReference) dm.m_boundServicesRefs.iterator().next();
-            }
-            else
-            {
-                // is it correct to assume an ordered bound services set ? 
-                int maxRanking = Integer.MIN_VALUE;
-                long minId = Long.MAX_VALUE;
-                selectedRef = null;
-                
-                Iterator it = dm.m_boundServicesRefs.iterator();
-                while (it.hasNext())
-                {
-                    ServiceReference ref = (ServiceReference) it.next();
-                    Integer rank = (Integer) ref.getProperty(Constants.SERVICE_RANKING);
-                    int ranking = (rank == null) ? Integer.MIN_VALUE : rank.intValue();
-                    long id = ((Long) ref.getProperty(Constants.SERVICE_ID)).longValue();
-                    if (maxRanking < ranking || (maxRanking == ranking && id < minId))
-                    {
-                        maxRanking = ranking;
-                        minId = id;
-                        selectedRef = ref;
-                    }
-                }
-            }
-    
-            // this is not realistic, as at least one service is available
-            // whose service id is smaller than Long.MAX_VALUE, still be sure
-            if (selectedRef == null)
-            {
-                return null;
-            }
-            
-            // return the service for the selected reference
-            return getBundleContext().getService(selectedRef);
-   	    }
-
-        public Object locateService(String name, ServiceReference ref) {
-            DependencyManager dm = getDependencyManager(name);
-            if (dm == null || dm.m_boundServicesRefs.isEmpty())
-            {
-                return null;
-            }
-            
-            // is it correct to assume an ordered bound services set ? 
-            Iterator it = dm.m_boundServicesRefs.iterator();
-            while (it.hasNext())
-            {
-                if (it.next().equals(ref))
-                {
-                    return getBundleContext().getService(ref);
-                }
-            }
-            
-            // no matching name and service reference found
-            return null;
-    	}
-
-        public Object[] locateServices(String name) {
-            DependencyManager dm = getDependencyManager(name);
-            if (dm == null || dm.m_boundServicesRefs.isEmpty())
-            {
-                return null;
-            }
-            
-            Object[] services = new Object[dm.m_boundServicesRefs.size()];
-            Iterator it = dm.m_boundServicesRefs.iterator();
-            for (int i=0; i < services.length && it.hasNext(); i++)
-            {
-                ServiceReference ref = (ServiceReference) it.next();
-                services[i] = getBundleContext().getService(ref);
-            }
-            return services;
-    	}
-
-        private DependencyManager getDependencyManager(String name) {
-            Iterator it = m_dependencyManagers.iterator();
-            while (it.hasNext())
-            {
-                DependencyManager dm = (DependencyManager)it.next();
-                
-                // if any of the dependency managers is unable to bind (it is invalid), the component is deactivated
-                if (name.equals(dm.m_dependencyMetadata.getName()))
-                {
-                    return dm;
-                }
-            }
-            
-            // not found
-            return null;
-        }
-        
-    	public BundleContext getBundleContext() {
-    		return m_activator.getBundleContext();
-    	}
-
-    	public Bundle getUsingBundle() {
-            return m_usingBundle;
-    	}
-
-    	public ComponentInstance getComponentInstance() {
-    		return ComponentManagerImpl.this;
-    	}
-
-    	public void enableComponent(String name) {
-    	    m_activator.enableComponent(name);
-    	}
-
-    	public void disableComponent(String name) {
-    	    m_activator.disableComponent(name);
-    	}
-
-    	public ServiceReference getServiceReference() {
-    		if(m_serviceRegistration != null) {
-    			return m_serviceRegistration.getReference();
-    		}
-    		else {
-    			return null;
-    		}
-    	}
-    }
-    
-    /**
-     * This class is a ServiceFactory that is used when a delayed component is created.
-     * This class returns the same service object instance for all bundles.
-     *
-     */
-    class DelayedComponentServiceFactory implements ServiceFactory {
-    	
-    	public Object getService(Bundle bundle, ServiceRegistration registration) {
-    		
-    	    Activator.trace("DelayedComponentServiceFactory.getService()", m_componentMetadata);
-    		// When the getServiceMethod is called, the implementation object must be created
-    		// unless another bundle has already retrievd it
-            
-            if (m_implementationObject == null) {
-                m_componentContext = new ComponentContextImpl(null);
-                m_implementationObject = createImplementationObject( m_componentContext );
-            }
-            
-            return m_implementationObject;
-    	}
-
-    	public void ungetService(Bundle bundle, ServiceRegistration registration, Object object) {
-            // nothing to do here, delayed components are deactivated when
-            // the component is deactivated and not when any bundle releases
-            // the service
-    	}
-        
-        protected Object createImplementationObject(ComponentContext componentContext) {
-            Object implementationObject;
-            
-            // 1. Load the component implementation class
-            // 2. Create the component instance and component context
-            // If the component is not immediate, this is not done at this moment
-            try
-            {
-                // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
-                Class c = m_activator.getBundleContext().getBundle().loadClass(m_componentMetadata.getImplementationClassName());
-                
-                // 112.4.4 The class must be public and have a public constructor without arguments so component instances
-                // may be created by the SCR with the newInstance method on Class
-                implementationObject = c.newInstance();
-            }
-            catch (Exception ex)
-            {
-                // TODO: manage this exception when implementation object cannot be created
-                Activator.exception("Error during instantiation of the implementation object",m_componentMetadata,ex);
-                deactivate();
-                //invalidate();
-                return null;
-            }
-            
-            
-            // 3. Bind the target services
-            Iterator it = m_dependencyManagers.iterator();
-
-            while ( it.hasNext() )
-            {
-                DependencyManager dm = (DependencyManager)it.next();
-                Iterator bound = dm.m_boundServicesRefs.iterator();
-                while ( bound.hasNext() ) {
-                    ServiceReference nextRef = (ServiceReference) bound.next();                 
-                    dm.invokeBindMethod(implementationObject, nextRef);
-                }
-            }
-            
-            // 4. Call the activate method, if present
-            // Search for the activate method
-            try {
-                Method activateMethod = getMethod(implementationObject.getClass(), "activate", new Class[]{ComponentContext.class});
-                activateMethod.invoke(implementationObject, new Object[]{componentContext});
-            }
-            catch(NoSuchMethodException ex) {
-                // We can safely ignore this one
-                Activator.trace("activate() method is not implemented", m_componentMetadata);
-            }
-            catch(IllegalAccessException ex) {
-                // Ignored, but should it be logged?
-                Activator.trace("activate() method cannot be called", m_componentMetadata);
-            }
-            catch(InvocationTargetException ex) {
-                // TODO: 112.5.8 If the activate method throws an exception, SCR must log an error message
-                // containing the exception with the Log Service
-                Activator.exception("The activate method has thrown an exception", m_componentMetadata, ex);
-            }
-            
-            return implementationObject;
-        }
-    }
-
-    /**
-     * This class is a ServiceFactory that is used when a delayed component is created
-     * for a service factory service
-     *
-     */
-    class DelayedServiceFactoryServiceFactory extends DelayedComponentServiceFactory
-    {
-        
-        // we do not have to maintain references to the actual service
-        // instances as those are handled by the ServiceManager and given
-        // to the ungetService method when the bundle releases the service
-        
-        // maintain the map of componentContext objects created for the
-        // service instances
-        private IdentityHashMap componentContexts = new IdentityHashMap();
-        
-        public Object getService( Bundle bundle, ServiceRegistration registration )
-        {
-
-            Activator.trace( "DelayedServiceFactoryServiceFactory.getService()", m_componentMetadata );
-            // When the getServiceMethod is called, the implementation object must be created
-
-            // private ComponentContext and implementation instances
-            ComponentContext componentContext = new ComponentContextImpl( bundle );
-            Object implementationObject = createImplementationObject( componentContext );
-
-            // register the components component context
-            componentContexts.put( implementationObject, componentContext );
-
-            return implementationObject;
-        }
-
-        public void ungetService( Bundle bundle, ServiceRegistration registration, Object implementationObject )
-        {
-            Activator.trace( "DelayedServiceFactoryServiceFactory.ungetService()", m_componentMetadata );
-            // When the ungetServiceMethod is called, the implementation object must be deactivated
-
-            // private ComponentContext and implementation instances
-            ComponentContext componentContext = ( ComponentContext ) componentContexts.remove( implementationObject );
-            deactivateImplementationObject( implementationObject, componentContext );
-        }
-        
-        protected void deactivateImplementationObject( Object implementationObject, ComponentContext componentContext )
-        {
-            // 1. Call the deactivate method, if present
-            // Search for the activate method
-            try
-            {
-                Method deactivateMethod = getMethod( implementationObject.getClass(), "deactivate", new Class[]
-                    { ComponentContext.class } );
-                deactivateMethod.invoke( implementationObject, new Object[]
-                    { componentContext } );
-            }
-            catch ( NoSuchMethodException ex )
-            {
-                // We can safely ignore this one
-                Activator.trace( "deactivate() method is not implemented", m_componentMetadata );
-            }
-            catch ( IllegalAccessException ex )
-            {
-                // Ignored, but should it be logged?
-                Activator.trace( "deactivate() method cannot be called", m_componentMetadata );
-            }
-            catch ( InvocationTargetException ex )
-            {
-                // TODO: 112.5.12 If the deactivate method throws an exception, SCR must log an error message
-                // containing the exception with the Log Service and continue
-                Activator.exception( "The deactivate method has thrown an exception", m_componentMetadata, ex );
-            }
-
-            // 2. Unbind any bound services
-            Iterator it = m_dependencyManagers.iterator();
-
-            while ( it.hasNext() )
-            {
-                DependencyManager dm = ( DependencyManager ) it.next();
-                Iterator bound = dm.m_boundServicesRefs.iterator();
-                while ( bound.hasNext() )
-                {
-                    ServiceReference nextRef = ( ServiceReference ) bound.next();
-                    dm.invokeUnbindMethod( implementationObject, nextRef );
-                }
-            }
-
-            // 3. Release all references
-            // nothing to do, we keep no references on per-Bundle services
-        }
-    }
-
-    /**
-     * Finds the named public or protected method in the given class or any
-     * super class. If such a method is found, its accessibility is enfored by
-     * calling the <code>Method.setAccessible</code> method if required and
-     * the method is returned. Enforcing accessibility is required to support
-     * invocation of protected methods.
-     * 
-     * @param clazz The <code>Class</code> which provides the method.
-     * @param name The name of the method.
-     * @param parameterTypes The parameters to the method. Passing
-     *      <code>null</code> is equivalent to using an empty array.
-     *      
-     * @return The named method with enforced accessibility
-     * 
-     * @throws NoSuchMethodException If no public or protected method with
-     *      the given name can be found in the class or any of its super classes.
-     */
-    private Method getMethod(Class clazz, String name, Class[] parameterTypes)
-        throws NoSuchMethodException 
-    {
-        // try the default mechanism first, which only yields public methods
-        try
-        {
-            return clazz.getMethod(name, parameterTypes); 
-        }
-        catch (NoSuchMethodException nsme)
-        {
-            // it is ok to not find a public method, try to find a protected now
-        }
-        
-        // now use method declarations, requiring walking up the class
-        // hierarchy manually. this algorithm also returns protected methods
-        // which is, what we need here
-        for ( ; clazz != null; clazz = clazz.getSuperclass()) 
-        {
-            try 
-            {
-                Method method = clazz.getDeclaredMethod(name, parameterTypes);
-                
-                // only accept a protected method, a public method should
-                // have been found above and neither private nor package
-                // protected methods are acceptable here
-                if (Modifier.isProtected(method.getModifiers())) {
-                    method.setAccessible(true);
-                    return method;
-                }
-            }
-            catch (NoSuchMethodException nsme)
-            {
-                // ignore for now
-            }
-        }
-        
-        // walked up the complete super class hierarchy and still not found
-        // anything, sigh ...
-        throw new NoSuchMethodException(name);
-    }    
-}
diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java b/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
new file mode 100644
index 0000000..9460390
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
@@ -0,0 +1,141 @@
+/* 
+ * 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.scr;
+
+
+import java.awt.Component;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.component.ComponentException;
+
+
+/**
+ * The <code>ComponentRegistry</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentRegistry implements ConfigurationListener
+{
+
+    // Known and registered ComponentManager instances
+    private Map m_componentNames;
+
+    // component id counter
+    private long m_componentCounter;
+
+    // the service registration of the ConfigurationListener service
+    private ServiceRegistration registration;
+
+
+    ComponentRegistry( BundleContext context )
+    {
+        m_componentNames = new HashMap();
+        m_componentCounter = -1;
+
+        Dictionary props = new Hashtable();
+        props.put( Constants.SERVICE_DESCRIPTION, "Service Component Configuration Support" );
+        props.put( Constants.SERVICE_VENDOR, "Apache Software Foundation" );
+        registration = context.registerService( ConfigurationListener.class.getName(), this, props );
+    }
+
+
+    void dispose()
+    {
+        if ( registration != null )
+        {
+            registration.unregister();
+            registration = null;
+        }
+    }
+
+
+    //---------- ConfigurationListener ----------------------------------------
+
+    public void configurationEvent( ConfigurationEvent configEvent )
+    {
+        String pid = configEvent.getPid();
+        ComponentManager cm = getComponent( pid );
+        if ( cm != null )
+        {
+            cm.reconfigure();
+        }
+    }
+
+
+    //---------- ComponentManager registration support ------------------------
+
+    long createComponentId()
+    {
+        m_componentCounter++;
+        return m_componentCounter;
+    }
+
+
+    void checkComponentName( String name )
+    {
+        if ( m_componentNames.containsKey( name ) )
+        {
+            throw new ComponentException( "The component name '" + name + "' has already been registered." );
+        }
+
+        // reserve the name
+        m_componentNames.put( name, name );
+    }
+
+
+    void registerComponent( String name, ComponentManager component )
+    {
+        // only register the component if there is a registration for it !
+        if ( !name.equals( m_componentNames.get( name ) ) )
+        {
+            // this is not expected if all works ok
+            throw new ComponentException( "The component name '" + name + "' has already been registered." );
+        }
+
+        m_componentNames.put( name, component );
+    }
+
+
+    ComponentManager getComponent( String name )
+    {
+        Object entry = m_componentNames.get( name );
+
+        // only return the entry if non-null and not a reservation
+        if ( entry instanceof ComponentManager )
+        {
+            return ( ComponentManager ) entry;
+        }
+
+        return null;
+    }
+
+
+    void unregisterComponent( String name )
+    {
+        m_componentNames.remove( name );
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java b/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
new file mode 100644
index 0000000..70f7e24
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
@@ -0,0 +1,84 @@
+/* 
+ * 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.scr;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * The <code>DelayedComponentManager</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev$, $Date$
+ */
+public class DelayedComponentManager extends ImmediateComponentManager implements ServiceFactory
+{
+
+    /**
+     * @param activator
+     * @param metadata
+     * @param componentId
+     */
+    public DelayedComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, long componentId )
+    {
+        super( activator, metadata, componentId );
+    }
+
+    protected void createComponent()
+    {
+        // nothing to do here for a delayed component, will be done in the
+        // getService method for the first bundle acquiring the component
+    }
+    
+    protected Object getService()
+    {
+        return this;
+    }
+    
+    //---------- ServiceFactory interface -------------------------------------
+    
+    public Object getService( Bundle arg0, ServiceRegistration arg1 )
+    {
+        Activator.trace("DelayedComponentServiceFactory.getService()", getComponentMetadata());
+        // When the getServiceMethod is called, the implementation object must be created
+        // unless another bundle has already retrievd it
+        
+        if (getInstance() == null) {
+            super.createComponent();
+            
+            // if component creation failed, we were deactivated and the state
+            // is not REGISTERED any more. Otherwise go to standard ACTIVE
+            // state now
+            if (getState() == STATE_REGISTERED)
+            {
+                setState( STATE_ACTIVE );
+            }
+        }
+        
+        return getInstance();
+    }
+    
+    public void ungetService( Bundle arg0, ServiceRegistration arg1, Object arg2 )
+    {
+        // nothing to do here
+    }
+    
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/DependencyManager.java
new file mode 100644
index 0000000..daf64c3
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/DependencyManager.java
@@ -0,0 +1,731 @@
+/* 
+ * 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.scr;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+
+/**
+ * The <code>DependencyManager</code> extends the <code>ServiceTracker</code>
+ * overwriting the {@link #addingService(ServiceReference)} and
+ * {@link #removedService(ServiceReference, Object)} methods to manage the
+ * a declared reference of a service component.
+ */
+class DependencyManager implements ServiceListener
+{
+    // mask of states ok to send events
+    private static final int STATE_MASK = AbstractComponentManager.STATE_UNSATISFIED
+        | AbstractComponentManager.STATE_ACTIVATING | AbstractComponentManager.STATE_ACTIVE
+        | AbstractComponentManager.STATE_REGISTERED | AbstractComponentManager.STATE_FACTORY;
+
+    // the component to which this dependency belongs
+    private AbstractComponentManager m_componentManager;
+
+    // Reference to the metadata
+    private ReferenceMetadata m_dependencyMetadata;
+
+    // A flag that defines if the bind method receives a ServiceReference
+    private boolean m_bindUsesServiceReference;
+
+    private Map m_tracked;
+
+
+    /**
+     * Constructor that receives several parameters.
+     * 
+     * @param dependency An object that contains data about the dependency
+     */
+    DependencyManager( AbstractComponentManager componentManager, ReferenceMetadata dependency )
+        throws InvalidSyntaxException
+    {
+        m_componentManager = componentManager;
+        m_dependencyMetadata = dependency;
+        m_bindUsesServiceReference = false;
+        m_tracked = new HashMap();
+
+        // register the service listener
+        String filterString = "(" + Constants.OBJECTCLASS + "=" + dependency.getInterface() + ")";
+        if ( dependency.getTarget() != null )
+        {
+            filterString = "(&" + filterString + dependency.getTarget() + ")";
+        }
+        componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
+
+        // initial registration of services
+        ServiceReference refs[] = componentManager.getActivator().getBundleContext().getServiceReferences( null,
+            filterString );
+        for ( int i = 0; refs != null && i < refs.length; i++ )
+        {
+            addingService( refs[i] );
+        }
+    }
+
+
+    //---------- ServiceListener interface ------------------------------------
+
+    public void serviceChanged( ServiceEvent event )
+    {
+        switch ( event.getType() )
+        {
+            case ServiceEvent.REGISTERED:
+                addingService( event.getServiceReference() );
+                break;
+            case ServiceEvent.MODIFIED:
+                removedService( event.getServiceReference() );
+                addingService( event.getServiceReference() );
+                break;
+            case ServiceEvent.UNREGISTERING:
+                removedService( event.getServiceReference() );
+                break;
+        }
+    }
+
+
+    //---------- Service tracking support -------------------------------------
+
+    /**
+     * Stops using this dependency manager
+     */
+    void close()
+    {
+        BundleContext context = m_componentManager.getActivator().getBundleContext();
+        context.removeServiceListener( this );
+
+        synchronized ( m_tracked )
+        {
+            for ( Iterator ri = m_tracked.keySet().iterator(); ri.hasNext(); )
+            {
+                ServiceReference sr = ( ServiceReference ) ri.next();
+                context.ungetService( sr );
+                ri.remove();
+            }
+        }
+    }
+
+
+    /**
+     * Returns the number of services currently tracked
+     */
+    int size()
+    {
+        synchronized ( m_tracked )
+        {
+            return m_tracked.size();
+        }
+    }
+
+
+    /**
+     * Returns a single (unspecified) service reference
+     */
+    ServiceReference getServiceReference()
+    {
+        synchronized ( m_tracked )
+        {
+            if ( m_tracked.size() > 0 )
+            {
+                return ( ServiceReference ) m_tracked.keySet().iterator().next();
+            }
+
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns an array of service references of the currently tracked
+     * services
+     */
+    ServiceReference[] getServiceReferences()
+    {
+        synchronized ( m_tracked )
+        {
+            if ( m_tracked.size() > 0 )
+            {
+                return ( ServiceReference[] ) m_tracked.keySet().toArray( new ServiceReference[m_tracked.size()] );
+            }
+
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns the service described by the ServiceReference
+     */
+    Object getService( ServiceReference serviceReference )
+    {
+        synchronized ( m_tracked )
+        {
+            return m_tracked.get( serviceReference );
+        }
+    }
+
+
+    /**
+     * Returns a single service instance
+     */
+    Object getService()
+    {
+        synchronized ( m_tracked )
+        {
+            if ( m_tracked.size() > 0 )
+            {
+                return m_tracked.values().iterator().next();
+            }
+
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns an array of service references of the currently tracked
+     * services
+     */
+    Object[] getServices()
+    {
+        synchronized ( m_tracked )
+        {
+            if ( m_tracked.size() > 0 )
+            {
+                return m_tracked.values().toArray( new ServiceReference[m_tracked.size()] );
+            }
+
+            return null;
+        }
+    }
+
+
+    //---------- DependencyManager core ---------------------------------------
+
+    /**
+     * Returns the name of the service reference.
+     */
+    String getName()
+    {
+        return m_dependencyMetadata.getName();
+    }
+
+
+    /**
+     * Returns <code>true</code> if we have at least one service reference or
+     * the dependency is optional.
+     */
+    boolean isValid()
+    {
+        return size() > 0 || m_dependencyMetadata.isOptional();
+    }
+
+
+    /**
+     * initializes a dependency. This method binds all of the service
+     * occurrences to the instance object
+     * 
+     * @return true if the operation was successful, false otherwise
+     */
+    boolean bind( Object instance )
+    {
+        // If no references were received, we have to check if the dependency
+        // is optional, if it is not then the dependency is invalid
+        if ( !isValid() )
+        {
+            return false;
+        }
+
+        // if the instance is null, we do nothing actually but assume success
+        // the instance might be null in the delayed component situation
+        if ( instance == null )
+        {
+            return true;
+        }
+
+        // Get service references
+        ServiceReference refs[] = getServiceReferences();
+
+        // refs can be null if the dependency is optional
+        if ( refs != null )
+        {
+            int max = 1;
+            boolean retval = true;
+
+            if ( m_dependencyMetadata.isMultiple() == true )
+            {
+                max = refs.length;
+            }
+
+            for ( int index = 0; index < max; index++ )
+            {
+                retval = invokeBindMethod( instance, refs[index], getService( refs[index] ) );
+                if ( retval == false && ( max == 1 ) )
+                {
+                    // There was an exception when calling the bind method
+                    Activator.error( "Dependency Manager: Possible exception in the bind method during initialize()",
+                        m_componentManager.getComponentMetadata() );
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Revoke all bindings. This method cannot throw an exception since it must
+     * try to complete all that it can
+     */
+    void unbind( Object instance )
+    {
+        // if the instance is null, we do nothing actually
+        // the instance might be null in the delayed component situation
+        if ( instance == null )
+        {
+            return;
+        }
+
+        ServiceReference[] allrefs = getServiceReferences();
+
+        if ( allrefs == null )
+            return;
+
+        for ( int i = 0; i < allrefs.length; i++ )
+        {
+            invokeUnbindMethod( instance, allrefs[i], getService( allrefs[i] ) );
+        }
+    }
+
+
+    /**
+     * Gets a bind or unbind method according to the policies described in the
+     * specification
+     * 
+     * @param methodname The name of the method
+     * @param targetClass the class to which the method belongs to
+     * @param parameterClassName the name of the class of the parameter that is
+     *            passed to the method
+     * @return the method or null
+     * @throws java.lang.ClassNotFoundException if the class was not found
+     */
+    private Method getBindingMethod( String methodname, Class targetClass, String parameterClassName )
+    {
+        Method method = null;
+
+        Class parameterClass = null;
+
+        // 112.3.1 The method is searched for using the following priority
+        // 1. The method's parameter type is org.osgi.framework.ServiceReference
+        // 2. The method's parameter type is the type specified by the
+        // reference's interface attribute
+        // 3. The method's parameter type is assignable from the type specified
+        // by the reference's interface attribute
+        try
+        {
+            // Case 1
+
+            method = AbstractComponentManager.getMethod( targetClass, methodname, new Class[]
+                { ServiceReference.class } );
+
+            m_bindUsesServiceReference = true;
+        }
+        catch ( NoSuchMethodException ex )
+        {
+
+            try
+            {
+                // Case2
+
+                m_bindUsesServiceReference = false;
+
+                parameterClass = m_componentManager.getActivator().getBundleContext().getBundle().loadClass(
+                    parameterClassName );
+
+                method = AbstractComponentManager.getMethod( targetClass, methodname, new Class[]
+                    { parameterClass } );
+            }
+            catch ( NoSuchMethodException ex2 )
+            {
+
+                // Case 3
+                method = null;
+
+                // iterate on class hierarchy
+                for ( ; method == null && targetClass != null; targetClass = targetClass.getSuperclass() )
+                {
+                    // Get all potential bind methods
+                    Method candidateBindMethods[] = targetClass.getDeclaredMethods();
+
+                    // Iterate over them
+                    for ( int i = 0; method == null && i < candidateBindMethods.length; i++ )
+                    {
+                        Method currentMethod = candidateBindMethods[i];
+
+                        // Get the parameters for the current method
+                        Class[] parameters = currentMethod.getParameterTypes();
+
+                        // Select only the methods that receive a single
+                        // parameter
+                        // and a matching name
+                        if ( parameters.length == 1 && currentMethod.getName().equals( methodname ) )
+                        {
+
+                            // Get the parameter type
+                            Class theParameter = parameters[0];
+
+                            // Check if the parameter type is assignable from
+                            // the type specified by the reference's interface
+                            // attribute
+                            if ( theParameter.isAssignableFrom( parameterClass ) )
+                            {
+
+                                // Final check: it must be public or protected
+                                if ( Modifier.isPublic( method.getModifiers() )
+                                    || Modifier.isProtected( method.getModifiers() ) )
+                                {
+                                    if ( !method.isAccessible() )
+                                    {
+                                        method.setAccessible( true );
+                                    }
+                                    method = currentMethod;
+
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch ( ClassNotFoundException ex2 )
+            {
+                Activator.exception( "Cannot load class used as parameter " + parameterClassName, m_componentManager
+                    .getComponentMetadata(), ex2 );
+            }
+        }
+
+        return method;
+    }
+
+
+    /**
+     * Call the bind method. In case there is an exception while calling the
+     * bind method, the service is not considered to be bound to the instance
+     * object
+     * 
+     * @param implementationObject The object to which the service is bound
+     * @param ref A ServiceReference with the service that will be bound to the
+     *            instance object
+     * @param storeRef A boolean that indicates if the reference must be stored
+     *            (this is used for the delayed components)
+     * @return true if the call was successful, false otherwise
+     */
+    private boolean invokeBindMethod( Object implementationObject, ServiceReference ref, Object service )
+    {
+        // The bind method is only invoked if the implementation object is not
+        // null. This is valid
+        // for both immediate and delayed components
+        if ( implementationObject != null )
+        {
+
+            try
+            {
+                // Get the bind method
+                Activator.trace( "getting bind: " + m_dependencyMetadata.getBind(), m_componentManager
+                    .getComponentMetadata() );
+                Method bindMethod = getBindingMethod( m_dependencyMetadata.getBind(), implementationObject.getClass(),
+                    m_dependencyMetadata.getInterface() );
+
+                if ( bindMethod == null )
+                {
+                    // 112.3.1 If the method is not found , SCR must log an
+                    // error
+                    // message with the log service, if present, and ignore the
+                    // method
+                    Activator.error( "bind() method not found", m_componentManager.getComponentMetadata() );
+                    return false;
+                }
+
+                // Get the parameter
+                Object parameter;
+
+                if ( m_bindUsesServiceReference == false )
+                {
+                    parameter = service;
+                }
+                else
+                {
+                    parameter = ref;
+                }
+
+                // Invoke the method
+                bindMethod.invoke( implementationObject, new Object[]
+                    { parameter } );
+
+                Activator.trace( "bound: " + getName(), m_componentManager.getComponentMetadata() );
+
+                return true;
+            }
+            catch ( IllegalAccessException ex )
+            {
+                // 112.3.1 If the method is not is not declared protected or
+                // public, SCR must log an error
+                // message with the log service, if present, and ignore the
+                // method
+                Activator.exception( "bind() method cannot be called", m_componentManager.getComponentMetadata(), ex );
+                return false;
+            }
+            catch ( InvocationTargetException ex )
+            {
+                Activator.exception( "DependencyManager : exception while invoking " + m_dependencyMetadata.getBind()
+                    + "()", m_componentManager.getComponentMetadata(), ex );
+                return false;
+            }
+        }
+        else if ( implementationObject == null && m_componentManager.getComponentMetadata().isImmediate() == false )
+        {
+            return true;
+        }
+        else
+        {
+            // this is not expected: if the component is immediate the
+            // implementationObject is not null (asserted by the caller)
+            return false;
+        }
+    }
+
+
+    /**
+     * Call the unbind method
+     * 
+     * @param implementationObject The object from which the service is unbound
+     * @param ref A service reference corresponding to the service that will be
+     *            unbound
+     * @return true if the call was successful, false otherwise
+     */
+    private boolean invokeUnbindMethod( Object implementationObject, ServiceReference ref, Object service )
+    {
+        // The unbind method is only invoked if the implementation object is not
+        // null. This is valid for both immediate and delayed components
+        if ( implementationObject != null )
+        {
+            try
+            {
+                Activator.trace( "getting unbind: " + m_dependencyMetadata.getUnbind(), m_componentManager
+                    .getComponentMetadata() );
+                Method unbindMethod = getBindingMethod( m_dependencyMetadata.getUnbind(), implementationObject
+                    .getClass(), m_dependencyMetadata.getInterface() );
+
+                // Recover the object that is bound from the map.
+                // Object parameter = m_boundServices.get(ref);
+                Object parameter = null;
+
+                if ( m_bindUsesServiceReference == true )
+                {
+                    parameter = ref;
+                }
+                else
+                {
+                    parameter = service;
+                }
+
+                if ( unbindMethod == null )
+                {
+                    // 112.3.1 If the method is not found , SCR must log an
+                    // error
+                    // message with the log service, if present, and ignore the
+                    // method
+                    Activator.error( "unbind() method not found", m_componentManager.getComponentMetadata() );
+                    return false;
+                }
+
+                unbindMethod.invoke( implementationObject, new Object[]
+                    { parameter } );
+
+                Activator.trace( "unbound: " + getName(), m_componentManager.getComponentMetadata() );
+
+                return true;
+            }
+            catch ( IllegalAccessException ex )
+            {
+                // 112.3.1 If the method is not is not declared protected or
+                // public, SCR must log an error
+                // message with the log service, if present, and ignore the
+                // method
+                Activator.exception( "unbind() method cannot be called", m_componentManager.getComponentMetadata(), ex );
+                return false;
+            }
+            catch ( InvocationTargetException ex )
+            {
+                Activator.exception( "DependencyManager : exception while invoking " + m_dependencyMetadata.getUnbind()
+                    + "()", m_componentManager.getComponentMetadata(), ex );
+                return false;
+            }
+
+        }
+        else if ( implementationObject == null && m_componentManager.getComponentMetadata().isImmediate() == false )
+        {
+            return true;
+        }
+        else
+        {
+            // this is not expected: if the component is immediate the
+            // implementationObject is not null (asserted by the caller)
+            return false;
+        }
+    }
+
+
+    private void addingService( ServiceReference reference )
+    {
+        // get the service and keep it here (for now or later)
+        Object service = m_componentManager.getActivator().getBundleContext().getService( reference );
+        synchronized ( m_tracked )
+        {
+            m_tracked.put( reference, service );
+        }
+
+        // forward the event if in event hanlding state
+        if ( handleServiceEvent() )
+        {
+
+            // the component is UNSATISFIED if enabled but any of the references
+            // have been missing when activate was running the last time or
+            // the component has been deactivated
+            if ( m_componentManager.getState() == AbstractComponentManager.STATE_UNSATISFIED )
+            {
+                m_componentManager.activate();
+            }
+
+            // Otherwise, this checks for dynamic 0..1, 0..N, and 1..N
+            // it never
+            // checks for 1..1 dynamic which is done above by the
+            // validate()
+            else if ( !m_dependencyMetadata.isStatic() )
+            {
+                // For dependency that are aggregates, always bind the
+                // service
+                // Otherwise only bind if bind services is zero, which
+                // captures the 0..1 case
+                // (size is still zero as we are called for the first service)
+                if ( m_dependencyMetadata.isMultiple() || size() == 0 )
+                {
+                    invokeBindMethod( m_componentManager.getInstance(), reference, service );
+                }
+            }
+        }
+    }
+
+
+    public void removedService( ServiceReference reference )
+    {
+        // remove the service from the internal registry, ignore if not cached
+        Object service;
+        synchronized ( m_tracked )
+        {
+            service = m_tracked.remove( reference );
+        }
+
+        // do nothing in the unlikely case that we do not have it cached
+        if ( service == null )
+        {
+            return;
+        }
+
+        if ( handleServiceEvent() )
+        {
+            // A static dependency is broken the instance manager will
+            // be invalidated
+            if ( m_dependencyMetadata.isStatic() )
+            {
+                // setStateDependency(DependencyChangeEvent.DEPENDENCY_INVALID);
+                try
+                {
+                    Activator.trace( "Dependency Manager: Static dependency is broken", m_componentManager
+                        .getComponentMetadata() );
+                    m_componentManager.reactivate();
+                }
+                catch ( Exception ex )
+                {
+                    Activator.exception( "Exception while recreating dependency ", m_componentManager
+                        .getComponentMetadata(), ex );
+                }
+            }
+            // dynamic dependency
+            else
+            {
+                // Release references to the service, call unbinder
+                // method
+                // and eventually request service unregistration
+                Object instance = m_componentManager.getInstance();
+                invokeUnbindMethod( instance, reference, service );
+
+                // The only thing we need to do here is check if we can
+                // reinitialize
+                // once the bound services becomes zero. This tries to
+                // repair dynamic
+                // 1..1 or rebind 0..1, since replacement services may
+                // be available.
+                // In the case of aggregates, this will only invalidate
+                // them since they
+                // can't be repaired.
+                if ( size() == 0 )
+                {
+                    // try to reinitialize
+                    if ( !bind( instance ) )
+                    {
+                        if ( !m_dependencyMetadata.isOptional() )
+                        {
+                            Activator
+                                .trace(
+                                    "Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...",
+                                    m_componentManager.getComponentMetadata() );
+                            m_componentManager.reactivate();
+                        }
+                    }
+                }
+            }
+        }
+
+        // finally unget the service
+        m_componentManager.getActivator().getBundleContext().ungetService( reference );
+    }
+
+
+    private boolean handleServiceEvent()
+    {
+        return ( m_componentManager.getState() & STATE_MASK ) != 0;
+        //        return state != AbstractComponentManager.INSTANCE_DESTROYING
+        //            && state != AbstractComponentManager.INSTANCE_DESTROYED
+        //            && state != AbstractComponentManager.INSTANCE_CREATING 
+        //            && state != AbstractComponentManager.INSTANCE_CREATED;
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
new file mode 100644
index 0000000..48b739f
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java
@@ -0,0 +1,299 @@
+/* 
+ * 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.scr;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The default ComponentManager. Objects of this class are responsible for managing
+ * implementation object's lifecycle.  
+ *
+ */
+class ImmediateComponentManager extends AbstractComponentManager
+{
+    // the component ID
+    private long m_componentId;
+
+    // The object that implements the service and that is bound to other services
+    private Object m_implementationObject = null;
+
+    // The context that will be passed to the implementationObject
+    private ComponentContext m_componentContext = null;
+    
+    // optional properties provided in the ComponentFactory.newInstance method
+    private Dictionary m_factoryProperties; 
+    
+    // the component properties, also used as service properties
+    private Dictionary m_properties; 
+    
+    /**
+     * The constructor receives both the activator and the metadata
+     * 
+     * @param activator
+     * @param metadata
+     */
+    ImmediateComponentManager(BundleComponentActivator activator, ComponentMetadata metadata, long componentId)
+    {
+        super(activator, metadata);
+        
+        m_componentId = componentId;
+    }
+  
+
+    // 1. Load the component implementation class
+    // 2. Create the component instance and component context
+    // 3. Bind the target services
+    // 4. Call the activate method, if present
+    protected void createComponent()
+    {
+        ComponentContext tmpContext = new ComponentContextImpl( this );
+        Object tmpObject = createImplementationObject( tmpContext );
+        
+        // if something failed craeating the object, we fell back to
+        // unsatisfied !!
+        if (tmpObject != null) {
+            m_componentContext = tmpContext;
+            m_implementationObject = tmpObject;
+        }
+    }
+    
+    protected void deleteComponent() {
+        deactivateImplementationObject( m_implementationObject, m_componentContext );
+        m_implementationObject = null;
+        m_componentContext = null;
+        m_properties = null;
+    }
+
+
+    //**********************************************************************************************************
+    
+    /**
+    * Get the object that is implementing this descriptor
+    *
+    * @return the object that implements the services
+    */
+    public Object getInstance() {
+        return m_implementationObject;
+    }
+
+    protected Object createImplementationObject(ComponentContext componentContext) {
+        Object implementationObject;
+        
+        // 1. Load the component implementation class
+        // 2. Create the component instance and component context
+        // If the component is not immediate, this is not done at this moment
+        try
+        {
+            // 112.4.4 The class is retrieved with the loadClass method of the component's bundle
+            Class c = getActivator().getBundleContext().getBundle().loadClass(getComponentMetadata().getImplementationClassName());
+            
+            // 112.4.4 The class must be public and have a public constructor without arguments so component instances
+            // may be created by the SCR with the newInstance method on Class
+            implementationObject = c.newInstance();
+        }
+        catch (Exception ex)
+        {
+            // failed to instantiate, deactivate the component and return null
+            Activator.exception( "Error during instantiation of the implementation object", getComponentMetadata(), ex );
+            deactivate();
+            return null;
+        }
+        
+        
+        // 3. Bind the target services
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            // if a dependency turned unresolved since the validation check,
+            // creating the instance fails here, so we deactivate and return
+            // null.
+            DependencyManager dm = ( DependencyManager ) it.next();
+            if ( !dm.bind( implementationObject ) )
+            {
+                Activator.error( "Cannot create component instance due to failure to bind reference " + dm.getName(),
+                    getComponentMetadata() );
+                deactivate();
+                return null;
+            }
+        }
+        
+        // 4. Call the activate method, if present
+        // Search for the activate method
+        try
+        {
+            Method activateMethod = getMethod( implementationObject.getClass(), "activate", new Class[]
+                { ComponentContext.class } );
+            activateMethod.invoke( implementationObject, new Object[]
+                { componentContext } );
+        }
+        catch ( NoSuchMethodException ex )
+        {
+            // We can safely ignore this one
+            Activator.trace( "activate() method is not implemented", getComponentMetadata() );
+        }
+        catch ( IllegalAccessException ex )
+        {
+            // Ignored, but should it be logged?
+            Activator.trace( "activate() method cannot be called", getComponentMetadata() );
+        }
+        catch ( InvocationTargetException ex )
+        {
+            // 112.5.8 If the activate method throws an exception, SCR must log an error message
+            // containing the exception with the Log Service
+            Activator.exception( "The activate method has thrown an exception", getComponentMetadata(), ex );
+        }
+        
+        return implementationObject;
+    }
+
+    protected void deactivateImplementationObject( Object implementationObject, ComponentContext componentContext )
+    {
+        // 1. Call the deactivate method, if present
+        // Search for the activate method
+        try
+        {
+            Method deactivateMethod = getMethod( implementationObject.getClass(), "deactivate", new Class[]
+                { ComponentContext.class } );
+            deactivateMethod.invoke( implementationObject, new Object[]
+                { componentContext } );
+        }
+        catch ( NoSuchMethodException ex )
+        {
+            // We can safely ignore this one
+            Activator.trace( "deactivate() method is not implemented", getComponentMetadata() );
+        }
+        catch ( IllegalAccessException ex )
+        {
+            // Ignored, but should it be logged?
+            Activator.trace( "deactivate() method cannot be called", getComponentMetadata() );
+        }
+        catch ( InvocationTargetException ex )
+        {
+            // 112.5.12 If the deactivate method throws an exception, SCR must log an error message
+            // containing the exception with the Log Service and continue
+            Activator.exception( "The deactivate method has thrown an exception", getComponentMetadata(), ex );
+        }
+
+        // 2. Unbind any bound services
+        Iterator it = getDependencyManagers();
+
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            dm.unbind( implementationObject );
+        }
+
+        // 3. Release all references
+        // nothing to do, we keep no references on per-Bundle services
+    }
+    
+    /**
+     * Returns the service object to be registered if the service element is
+     * specified.
+     * <p>
+     * Extensions of this class may overwrite this method to return a
+     * ServiceFactory to register in the case of a delayed or a service
+     * factory component. 
+     */
+    protected Object getService() {
+        return m_implementationObject;
+    }
+    
+    protected void setFactoryProperties(Dictionary dictionary) {
+        m_factoryProperties = copyTo( null, dictionary );
+    }
+    
+    /**
+     * Returns the (private copy) of the Component properties to be used
+     * for the ComponentContext as well as eventual service registration.
+     * <p>
+     * Method implements the Component Properties provisioning as described
+     * in 112.6, Component Properties.
+     * 
+     * @return a private Hashtable of component properties
+     */
+    protected Dictionary getProperties()
+    {
+
+        // TODO: Currently on ManagedService style configuration is supported, ManagedServiceFactory style is missing
+
+        if ( m_properties == null )
+        {
+
+            // 1. the properties from the component descriptor
+            Dictionary props = copyTo( null, getComponentMetadata().getProperties() );
+
+            // 2. overlay with Configuration Admin properties
+            ConfigurationAdmin ca = getActivator().getConfigurationAdmin();
+            if ( ca != null )
+            {
+                try
+                {
+                    Configuration cfg = ca.getConfiguration( getComponentMetadata().getName() );
+                    if (cfg != null) {
+                        copyTo( props, cfg.getProperties() );
+                    }
+                }
+                catch ( IOException ioe )
+                {
+                    Activator.exception( "Problem getting Configuration", getComponentMetadata(), ioe );
+                }
+            }
+
+            // 3. copy any component factory properties, not supported yet
+            copyTo( props, m_factoryProperties );
+            
+            // 4. set component.name and component.id
+            props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
+            props.put( ComponentConstants.COMPONENT_ID, new Long( m_componentId ) );
+            
+            m_properties = props;
+        }
+
+        return m_properties;
+    }
+    
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java b/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java
index 1903781..f326a0f 100644
--- a/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java
+++ b/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java
@@ -18,15 +18,34 @@
  */

 package org.apache.felix.scr;

 

+

 /**

  * This factory allows other types of ComponentManagers to be provided.

  * 

  * 

  */

-public class ManagerFactory {

-	

-	static ComponentManager createManager(BundleComponentActivator activator, ComponentMetadata metadata) {

-	    Activator.trace("ManagerFactory.createManager", metadata);

-	    return new ComponentManagerImpl(activator,metadata);

-	}

+public class ManagerFactory

+{

+

+    static ComponentManager createManager( BundleComponentActivator activator, ComponentMetadata metadata,

+        long componentId )

+    {

+        Activator.trace( "ManagerFactory.createManager", metadata );

+        if ( metadata.isImmediate() )

+        {

+            return new ImmediateComponentManager( activator, metadata, componentId );

+        }

+        else if ( metadata.getServiceMetadata() != null )

+        {

+            if ( metadata.getServiceMetadata().isServiceFactory() )

+            {

+                return new ServiceFactoryComponentManager( activator, metadata, componentId );

+            }

+

+            return new DelayedComponentManager( activator, metadata, componentId );

+        }

+

+        // if we get here, which is not expected after all, we fail

+        throw new IllegalArgumentException( "Cannot create a component manager for " + metadata.getName() );

+    }

 }
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/ReadOnlyDictionary.java b/scr/src/main/java/org/apache/felix/scr/ReadOnlyDictionary.java
new file mode 100644
index 0000000..6350535
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ReadOnlyDictionary.java
@@ -0,0 +1,108 @@
+/* 
+ * 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.scr;
+
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+
+/**
+ * The <code>ReadOnlyDictionary</code> is a <code>Dictionary</code> whose
+ * {@link #put(Object, Object)} and {@link #remove(Object)} methods have 
+ * no effect and always return <code>null</code>.
+ *
+ * @author fmeschbe
+ */
+public class ReadOnlyDictionary extends Dictionary
+{
+
+    private Dictionary delegatee;
+
+
+    ReadOnlyDictionary( Dictionary delegatee )
+    {
+        this.delegatee = delegatee;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.util.Dictionary#elements()
+     */
+    public Enumeration elements()
+    {
+        return delegatee.elements();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.util.Dictionary#get(java.lang.Object)
+     */
+    public Object get( Object key )
+    {
+        return delegatee.get( key );
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.util.Dictionary#isEmpty()
+     */
+    public boolean isEmpty()
+    {
+        return delegatee.isEmpty();
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.util.Dictionary#keys()
+     */
+    public Enumeration keys()
+    {
+        return delegatee.keys();
+    }
+
+
+    /**
+     * This method has no effect and always returns <code>null</code> as this
+     * instance is read-only and cannot modify and properties.
+     */
+    public Object put( Object arg0, Object arg1 )
+    {
+        return null;
+    }
+
+
+    /**
+     * This method has no effect and always returns <code>null</code> as this
+     * instance is read-only and cannot modify and properties.
+     */
+    public Object remove( Object key )
+    {
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see java.util.Dictionary#size()
+     */
+    public int size()
+    {
+        return delegatee.size();
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java
new file mode 100644
index 0000000..9e476dd
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java
@@ -0,0 +1,180 @@
+/* 
+ * 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.scr;
+
+
+import java.util.IdentityHashMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The <code>ServiceFactoryComponentManager</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev$, $Date$
+ */
+public class ServiceFactoryComponentManager extends ImmediateComponentManager implements ServiceFactory
+{
+
+    // we do not have to maintain references to the actual service
+    // instances as those are handled by the ServiceManager and given
+    // to the ungetService method when the bundle releases the service
+
+    // maintain the map of componentContext objects created for the
+    // service instances
+    private IdentityHashMap componentContexts = new IdentityHashMap();
+
+
+    /**
+     * @param activator
+     * @param metadata
+     */
+    public ServiceFactoryComponentManager( BundleComponentActivator activator, ComponentMetadata metadata,
+        long componentId )
+    {
+        super( activator, metadata, componentId );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.AbstractComponentManager#createComponent()
+     */
+    protected void createComponent()
+    {
+        // nothing to do, this is handled by getService
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.AbstractComponentManager#deleteComponent()
+     */
+    protected void deleteComponent()
+    {
+        // nothing to do, this is handled by ungetService
+    }
+
+
+    protected Object getService()
+    {
+        return this;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.AbstractComponentManager#getInstance()
+     */
+    public Object getInstance()
+    {
+        // this method is not expected to be called as the base call is
+        // overwritten in the BundleComponentContext class
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     */
+    public Object getService( Bundle bundle, ServiceRegistration registration )
+    {
+        Activator.trace( "DelayedServiceFactoryServiceFactory.getService()", getComponentMetadata() );
+        // When the getServiceMethod is called, the implementation object must be created
+
+        // private ComponentContext and implementation instances
+        BundleComponentContext componentContext = new BundleComponentContext( this, bundle );
+        Object implementationObject = createImplementationObject( componentContext );
+
+        // register the components component context if successfull
+        if (implementationObject != null) {
+            componentContext.setImplementationObject( implementationObject );
+            componentContexts.put( implementationObject, componentContext );
+
+            // if this is the first use of this component, switch to ACTIVE state
+            if (getState() == STATE_REGISTERED)
+            {
+                setState( STATE_ACTIVE );
+            }
+        }
+        
+        return implementationObject;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+     */
+    public void ungetService( Bundle bundle, ServiceRegistration registration, Object service )
+    {
+        Activator.trace( "DelayedServiceFactoryServiceFactory.ungetService()", getComponentMetadata() );
+        // When the ungetServiceMethod is called, the implementation object must be deactivated
+
+        // private ComponentContext and implementation instances
+        ComponentContext componentContext = ( ComponentContext ) componentContexts.remove( service );
+        deactivateImplementationObject( service, componentContext );
+        
+        // if this was the last use of the component, go back to REGISTERED state
+        if ( componentContexts.isEmpty() && getState() == STATE_ACTIVE )
+        {
+            setState( STATE_REGISTERED );
+        }
+    }
+
+    private static class BundleComponentContext extends ComponentContextImpl implements ComponentInstance {
+        
+        private Bundle m_usingBundle;
+        private Object m_implementationObject;
+
+        BundleComponentContext(AbstractComponentManager componentManager, Bundle usingBundle) {
+            super(componentManager);
+            
+            m_usingBundle = usingBundle;
+        }
+        
+        private void setImplementationObject( Object implementationObject )
+        {
+            m_implementationObject = implementationObject;
+        }
+        
+        public Bundle getUsingBundle()
+        {
+            return m_usingBundle;
+        }
+        
+        public ComponentInstance getComponentInstance()
+        {
+            return this;
+        }
+        
+        //---------- ComponentInstance interface ------------------------------
+        
+        public Object getInstance()
+        {
+            return m_implementationObject;
+        }
+        
+        public void dispose()
+        {
+            getComponentManager().dispose();
+        }
+    }
+}