diff --git a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java b/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
index 2b79da7..c43b1e2 100644
--- a/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
@@ -1,1193 +1,1193 @@
-/*
- *   Copyright 2006 The Apache Software Foundation
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-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;
-
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
 
-/**
- * The default ComponentManager. Objects of this class are responsible for managing
- * implementation object's lifecycle.  
- *
- */
-public 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
+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.  
+ *
+ */
+public 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 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 GenericActivator
     private GenericActivator m_activator = null;
 
-    // The context that will be passed to the implementationObject
+    // 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 DelayedComponentServiceFactory m_delayedComponentServiceFactory;
-    
-    /**
-     * The constructor receives both the activator and the metadata
-     * 
-     * @param activator
-     * @param metadata
-     */
-    ComponentManagerImpl(GenericActivator 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() {
-    	
-    	GenericActivator.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 )
-        {
-        	//GenericActivator.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
-	            GenericActivator.exception("Error during instantiation", m_componentMetadata, ex);
-	            deactivate();
-	            //invalidate();
-	            return;
-	        }
-        } else {
-        	m_delayedComponentServiceFactory = new DelayedComponentServiceFactory();
-        }
-        
-        // 3. Bind the target services
-        it = m_dependencyManagers.iterator();
-
-        //GenericActivator.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;
-            }
-        }
-        
-        //GenericActivator.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
-        		GenericActivator.trace("activate() method not implemented", m_componentMetadata);
-        	}
-        	catch(IllegalAccessException ex) {
-        		// TODO: Log this exception?
-        		GenericActivator.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
-        		GenericActivator.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)
-        {
-            GenericActivator.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;
-
-	        GenericActivator.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
-			GenericActivator.trace("deactivate() method is not implemented", m_componentMetadata);
-		}
-		catch(IllegalAccessException ex) {
-			// Ignored, but should it be logged?
-			GenericActivator.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
-			GenericActivator.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;
-
-        //GenericActivator.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 GenericActivator 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) {
-    	GenericActivator.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));
-        }
+    
+    // In case of a delayed component, this holds a reference to the factory
+    private DelayedComponentServiceFactory m_delayedComponentServiceFactory;
+    
+    /**
+     * The constructor receives both the activator and the metadata
+     * 
+     * @param activator
+     * @param metadata
+     */
+    ComponentManagerImpl(GenericActivator 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() {
+    	
+    	GenericActivator.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 )
+        {
+        	//GenericActivator.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
+	            GenericActivator.exception("Error during instantiation", m_componentMetadata, ex);
+	            deactivate();
+	            //invalidate();
+	            return;
+	        }
+        } else {
+        	m_delayedComponentServiceFactory = new DelayedComponentServiceFactory();
+        }
+        
+        // 3. Bind the target services
+        it = m_dependencyManagers.iterator();
+
+        //GenericActivator.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;
+            }
+        }
+        
+        //GenericActivator.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
+        		GenericActivator.trace("activate() method not implemented", m_componentMetadata);
+        	}
+        	catch(IllegalAccessException ex) {
+        		// TODO: Log this exception?
+        		GenericActivator.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
+        		GenericActivator.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)
+        {
+            GenericActivator.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;
+
+	        GenericActivator.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
+			GenericActivator.trace("deactivate() method is not implemented", m_componentMetadata);
+		}
+		catch(IllegalAccessException ex) {
+			// Ignored, but should it be logged?
+			GenericActivator.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
+			GenericActivator.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;
+
+        //GenericActivator.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 GenericActivator 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) {
+    	GenericActivator.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
-    {
+ * 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(refs[index]);
-                    if(retval == false && (max == 1))
-                    {
-                        // There was an exception when calling the bind method
-                        GenericActivator.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((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)
-            {
-                GenericActivator.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) {
-            		GenericActivator.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 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(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(m_implementationObject != null) {
-        		
-		        try {
-		        	// Get the bind method
-		            Method bindMethod = getBindingMethod(m_dependencyMetadata.getBind(),  getInstance().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
-		            	GenericActivator.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(getInstance(),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)
-		        {
-		        	GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getBind()+"()", m_componentMetadata, ex);
-		            return false;
-		        }
-        	} else if( m_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 ref A service reference corresponding to the service that will be unbound
-         * @return true if the call was successful, false otherwise
-        **/
-        private boolean invokeUnbindMethod(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 ( m_implementationObject != null ) {
-	            try
-	            {
-	            	// TODO: me quede aqui por que el unbind method no funciona
-	            	GenericActivator.trace("getting unbind: "+m_dependencyMetadata.getUnbind(), m_componentMetadata);
-	            	Method unbindMethod = getBindingMethod(m_dependencyMetadata.getUnbind(), getInstance().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
-	                	GenericActivator.trace("unbind() method not found", m_componentMetadata);
-	                	return false;
-	                }
-	
-	            	unbindMethod.invoke(getInstance(),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) {
-	            	GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbind()+"()", m_componentMetadata, ex);
-	            	return false;
-	            }
-	            
-        	} else if( m_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
-                            {
-                                GenericActivator.trace("Dependency Manager: Static dependency is broken", m_componentMetadata);
-                                deactivate();
-                                GenericActivator.trace("Dependency Manager: RECREATING", m_componentMetadata);
-                                activate();
-                            }
-                            catch(Exception ex)
-                            {
-                            	GenericActivator.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(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())
-                                    {
-                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...", m_componentMetadata);
-                                        deactivate();
-                                        GenericActivator.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
-                        GenericActivator.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(evt.getServiceReference());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Implementation for the ComponentContext interface
-     *
+        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(refs[index]);
+                    if(retval == false && (max == 1))
+                    {
+                        // There was an exception when calling the bind method
+                        GenericActivator.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((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)
+            {
+                GenericActivator.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) {
+            		GenericActivator.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 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(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(m_implementationObject != null) {
+        		
+		        try {
+		        	// Get the bind method
+		            Method bindMethod = getBindingMethod(m_dependencyMetadata.getBind(),  getInstance().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
+		            	GenericActivator.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(getInstance(),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)
+		        {
+		        	GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getBind()+"()", m_componentMetadata, ex);
+		            return false;
+		        }
+        	} else if( m_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 ref A service reference corresponding to the service that will be unbound
+         * @return true if the call was successful, false otherwise
+        **/
+        private boolean invokeUnbindMethod(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 ( m_implementationObject != null ) {
+	            try
+	            {
+	            	// TODO: me quede aqui por que el unbind method no funciona
+	            	GenericActivator.trace("getting unbind: "+m_dependencyMetadata.getUnbind(), m_componentMetadata);
+	            	Method unbindMethod = getBindingMethod(m_dependencyMetadata.getUnbind(), getInstance().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
+	                	GenericActivator.trace("unbind() method not found", m_componentMetadata);
+	                	return false;
+	                }
+	
+	            	unbindMethod.invoke(getInstance(),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) {
+	            	GenericActivator.exception("DependencyManager : exception while invoking "+m_dependencyMetadata.getUnbind()+"()", m_componentMetadata, ex);
+	            	return false;
+	            }
+	            
+        	} else if( m_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
+                            {
+                                GenericActivator.trace("Dependency Manager: Static dependency is broken", m_componentMetadata);
+                                deactivate();
+                                GenericActivator.trace("Dependency Manager: RECREATING", m_componentMetadata);
+                                activate();
+                            }
+                            catch(Exception ex)
+                            {
+                            	GenericActivator.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(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())
+                                    {
+                                        GenericActivator.trace("Dependency Manager: Mandatory dependency not fullfilled and no replacements available... unregistering service...", m_componentMetadata);
+                                        deactivate();
+                                        GenericActivator.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
+                        GenericActivator.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(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 arg0) {
-    		// TODO implement this method
-    		
-    	}
-
-    	public void disableComponent(String arg0) {
-    		// TODO implement this method
-    		
-    	}
-
-    	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
-     *
-     */
-    class DelayedComponentServiceFactory implements ServiceFactory {
-    	
-    	public Object getService(Bundle arg0, ServiceRegistration arg1) {
-    		
-    		GenericActivator.trace("DelayedComponentServiceFactory.getService()", m_componentMetadata);
-    		// When the getServiceMethod is called, the implementation object must be created
-    		
-            // 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
-	            m_componentContext = new ComponentContextImpl(arg0);
-	            m_implementationObject = c.newInstance();
-	        }
-	        catch (Exception ex)
-	        {
-	            // TODO: manage this exception when implementation object cannot be created
-	            GenericActivator.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(nextRef);
-	            }
-	        }
-	        
-	        // 4. Call the activate method, if present
-            // 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
-                GenericActivator.trace("activate() method is not implemented", m_componentMetadata);
-            }
-            catch(IllegalAccessException ex) {
-                // Ignored, but should it be logged?
-                GenericActivator.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
-                GenericActivator.exception("The activate method has thrown and exception", m_componentMetadata, ex);
-            }
-    		
-    		return m_implementationObject;
-    	}
-
-    	public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
-    		// TODO Auto-generated method stub
-
-    	}
-    }
-
-    /**
-     * 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);
-    }    
-}
\ No newline at end of file
+    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 arg0) {
+    		// TODO implement this method
+    		
+    	}
+
+    	public void disableComponent(String arg0) {
+    		// TODO implement this method
+    		
+    	}
+
+    	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
+     *
+     */
+    class DelayedComponentServiceFactory implements ServiceFactory {
+    	
+    	public Object getService(Bundle arg0, ServiceRegistration arg1) {
+    		
+    		GenericActivator.trace("DelayedComponentServiceFactory.getService()", m_componentMetadata);
+    		// When the getServiceMethod is called, the implementation object must be created
+    		
+            // 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
+	            m_componentContext = new ComponentContextImpl(arg0);
+	            m_implementationObject = c.newInstance();
+	        }
+	        catch (Exception ex)
+	        {
+	            // TODO: manage this exception when implementation object cannot be created
+	            GenericActivator.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(nextRef);
+	            }
+	        }
+	        
+	        // 4. Call the activate method, if present
+            // 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
+                GenericActivator.trace("activate() method is not implemented", m_componentMetadata);
+            }
+            catch(IllegalAccessException ex) {
+                // Ignored, but should it be logged?
+                GenericActivator.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
+                GenericActivator.exception("The activate method has thrown and exception", m_componentMetadata, ex);
+            }
+    		
+    		return m_implementationObject;
+    	}
+
+    	public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
+    		// TODO Auto-generated method stub
+
+    	}
+    }
+
+    /**
+     * 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/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
index 8fe037e..707b13f 100644
--- a/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/ComponentMetadata.java
@@ -1,301 +1,298 @@
-/*
- *   Copyright 2006 The Apache Software Foundation
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-package org.apache.felix.scr;
-
-import java.util.*;
-
-import org.osgi.service.component.ComponentException;
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
+
+import java.util.*;
+
+import org.osgi.service.component.ComponentException;
 
 /**
- * This class holds the information associated to a component in the descriptor *  */
-public class ComponentMetadata {
-	// 112.4.3: A Globally unique component name (required)
-	private String m_name;
-	
-	// 112.4.3: Controls whether the component is enabled when the bundle is started. (optional, default is true).
-	private boolean m_enabled = true;
-	
-	// 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
-	private String m_factory = null;
-	
-	// 112.4.3: Controls whether component configurations must be immediately activated after becoming 
-	// satisfied or whether activation should be delayed. (optional, default value is false).
-	private boolean m_immediate = false;
-	
-    // 112.4.4 Implementation Element (required)
-    private String m_implementationClassName = null;
-    
-    // Associated properties (0..*)
-    private Dictionary m_properties = new Hashtable();
-    
-    // List of Property metadata - used while building the meta data
-    // while validating the properties contained in the PropertyMetadata
-    // instances are copied to the m_properties Dictionary while this
-    // list will be cleared
-    private List m_propertyMetaData = new ArrayList();
-    
-    // Provided services (0..1)
-    private ServiceMetadata m_service = null;
-    
-    // List of service references, (required services 0..*)
-    private List m_references = new ArrayList();
-    
-    // Flag that is set once the component is verified (its properties cannot be changed)
-    private boolean m_validated = false;
-        
-       
-    /////////////////////////////////////////// SETTERS //////////////////////////////////////
-    
-    /**
-     * Setter for the name
-     * 
-     * @param name
-     */
-    public void setName(String name) {
-    	if(m_validated) {
-    		return;
-    	}
-    	m_name = name;
-    }
-    
-    /**
-     * Setter for the enabled property
-     * 
-     * @param enabled
-     */
-    public void setEnabled(boolean enabled) {
-    	if(m_validated) {
-    		return;
-    	}
-    	m_enabled = enabled;
-    }
-    
-    /**
-     * 
-     * @param factoryIdentifier
-     */
-    public void setFactoryIdentifier(String factoryIdentifier) {
-    	if(m_validated) {
-    		return;
-    	}
-    	m_factory = factoryIdentifier;
-    }
-    
-    /**
-     * Setter for the immediate property
-     * 
-     * @param immediate
-     */
-    public void setImmediate(boolean immediate) {
-    	if(m_validated) {
-    		return;
-    	}
-    	m_immediate = immediate;
-    }   
-    
-    /**
-     * Sets the name of the implementation class
-     * 
-     * @param implementationClassName a class name
-     */
-    public void setImplementationClassName(String implementationClassName) {
-    	if(m_validated) {
-    		return;
-    	}
-        m_implementationClassName = implementationClassName;
-    }
-
-    /**
-     * Used to add a property to the instance
-     *
-     * @param newProperty a property metadata object
-     */
-    public void addProperty(PropertyMetadata newProperty) {
-    	if(m_validated) {
-    		return;
-    	}
-    	if(newProperty == null) {
-    		throw new IllegalArgumentException ("Cannot add a null property");
-    	}
-    	m_propertyMetaData.add(newProperty);
-    }
-
-    /**
-     * Used to set a ServiceMetadata object.
-     *
-     * @param service a ServiceMetadata
-     */
-    public void setService(ServiceMetadata service) {
-    	if(m_validated) {
-    		return;
-    	}
-        m_service = service;
-    }
-
-    /**
-     * Used to add a reference metadata to the component
-     *
-     * @param newReference a new ReferenceMetadata to be added
-     */
-    public void addDependency(ReferenceMetadata newReference) {
-    	if(newReference == null) {
-    		throw new IllegalArgumentException ("Cannot add a null ReferenceMetadata");
-    	}
-        m_references.add(newReference);
-    }
-
-    
-    /////////////////////////////////////////// GETTERS //////////////////////////////////////
-    
-    /**
-     * Returns the name of the component
-     * 
-     * @return A string containing the name of the component 
-     */
-    public String getName() {
-    	return m_name;
-    }
-    
-    /**
-     * Returns the value of the enabled flag 
-     * 
-     * @return a boolean containing the value of the enabled flag
-     */
-    public boolean isEnabled() {
-    	return m_enabled;
-    }
-
-    /**
-     * Returns the factory identifier
-     * 
-     * @return A string containing a factory identifier or null
-     */
-    public String getFactoryIdentifier() {
-    	return m_factory;
-    }
-    
-    /**
-     * Returns the flag that defines the activation policy for the component
-     * 
-     * @return a boolean that defines the activation policy
-     */
-    public boolean isImmediate() {
-    	return m_immediate;
-    }
-    
-    /**
-     * Returns the name of the implementation class
-     *
-     * @return the name of the implementation class
-     */
-    public String getImplementationClassName() {
-        return m_implementationClassName;
-    }
-
-    /**
-     * Returns the associated ServiceMetadata
-     * 
-     * @return a ServiceMetadata object or null if the Component does not provide any service
-     */
-    public ServiceMetadata getServiceMetadata() {
-    	return m_service;
-    }
-
-    /**
-     * Returns the properties.
-     *
-     * @return the properties as a Dictionary
-     */
-    public Dictionary getProperties() {
-        return m_properties;
-    }
-
-    /**
-     * Returns the dependency descriptors
-     *
-     * @return a Collection of dependency descriptors
-     */
-    public List getDependencies() {
-        return m_references;
-    }
-
-    /**
-     * Test to see if this service is a factory
-     *
-     * @return true if it is a factory, false otherwise
-     */
-    public boolean isFactory() {
-        return m_factory != null;
-    }
-    
-    /**
-     * Method used to verify if the semantics of this metadata are correct
-     */
-    void validate() {
-    	
-        // First check if the properties are valid (and extract property values)
-        Iterator propertyIterator = m_propertyMetaData.iterator();
-    	while ( propertyIterator.hasNext() ) {
-    	    PropertyMetadata propMeta = (PropertyMetadata) propertyIterator.next();
-            propMeta.validate();
-            m_properties.put(propMeta.getName(), propMeta.getValue());
-        }
-    	m_propertyMetaData.clear();
-    	
-    	// Check that the provided services are valid too
-    	if(m_service != null) {
-    		m_service.validate();
-    	}
-    	
-    	// Check that the references are ok
-    	Iterator referenceIterator = m_references.iterator();
-    	while ( referenceIterator.hasNext() ) {
-    		((ReferenceMetadata)referenceIterator.next()).validate();
-    	}
-    	    	
-    	// 112.10 The name of the component is required
-    	if( m_name == null ) {
-    		throw new ComponentException("The component name has not been set");
-    	}
-    	
-    	// 112.10 There must be one implementation element and the class atribute is required
-    	if ( m_implementationClassName == null ) {
-    		throw new ComponentException("The implementation class name has not been set for this component");
-    	}
-    	
-    	// 112.2.3 A delayed component specifies a service, is not specified to be a factory component
-    	// and does not have the immediate attribute of the component element set to true.
-    	if(m_immediate == false && m_service == null) {
-    		throw new ComponentException("Component '"+m_name+"' is specified as being delayed but does not provide any service.");
-    	}    	
-    	
-    	if ( m_factory != null && m_immediate == false) {
-    		throw new ComponentException("A factory cannot be a delayed component");
-    	}
-    	
-    	// TODO: 112.4.6 The serviceFactory attribute (of a provided service) must not be true if 
-    	// the component is a factory component or an immediate component
-
-    	
-    	m_validated = true;
-    	// TODO: put a similar flag on the references and the services
-    }
-
-}
-
-
-
+ * This class holds the information associated to a component in the descriptor *  */
+public class ComponentMetadata {
+	// 112.4.3: A Globally unique component name (required)
+	private String m_name;
+	
+	// 112.4.3: Controls whether the component is enabled when the bundle is started. (optional, default is true).
+	private boolean m_enabled = true;
+	
+	// 112.4.3: Factory identified. If set to a non empty string, it indicates that the component is a factory component (optional).
+	private String m_factory = null;
+	
+	// 112.4.3: Controls whether component configurations must be immediately activated after becoming 
+	// satisfied or whether activation should be delayed. (optional, default value is false).
+	private boolean m_immediate = false;
+	
+    // 112.4.4 Implementation Element (required)
+    private String m_implementationClassName = null;
+    
+    // Associated properties (0..*)
+    private Dictionary m_properties = new Hashtable();
+    
+    // List of Property metadata - used while building the meta data
+    // while validating the properties contained in the PropertyMetadata
+    // instances are copied to the m_properties Dictionary while this
+    // list will be cleared
+    private List m_propertyMetaData = new ArrayList();
+    
+    // Provided services (0..1)
+    private ServiceMetadata m_service = null;
+    
+    // List of service references, (required services 0..*)
+    private List m_references = new ArrayList();
+    
+    // Flag that is set once the component is verified (its properties cannot be changed)
+    private boolean m_validated = false;
+        
+       
+    /////////////////////////////////////////// SETTERS //////////////////////////////////////
+    
+    /**
+     * Setter for the name
+     * 
+     * @param name
+     */
+    public void setName(String name) {
+    	if(m_validated) {
+    		return;
+    	}
+    	m_name = name;
+    }
+    
+    /**
+     * Setter for the enabled property
+     * 
+     * @param enabled
+     */
+    public void setEnabled(boolean enabled) {
+    	if(m_validated) {
+    		return;
+    	}
+    	m_enabled = enabled;
+    }
+    
+    /**
+     * 
+     * @param factoryIdentifier
+     */
+    public void setFactoryIdentifier(String factoryIdentifier) {
+    	if(m_validated) {
+    		return;
+    	}
+    	m_factory = factoryIdentifier;
+    }
+    
+    /**
+     * Setter for the immediate property
+     * 
+     * @param immediate
+     */
+    public void setImmediate(boolean immediate) {
+    	if(m_validated) {
+    		return;
+    	}
+    	m_immediate = immediate;
+    }   
+    
+    /**
+     * Sets the name of the implementation class
+     * 
+     * @param implementationClassName a class name
+     */
+    public void setImplementationClassName(String implementationClassName) {
+    	if(m_validated) {
+    		return;
+    	}
+        m_implementationClassName = implementationClassName;
+    }
+
+    /**
+     * Used to add a property to the instance
+     *
+     * @param newProperty a property metadata object
+     */
+    public void addProperty(PropertyMetadata newProperty) {
+    	if(m_validated) {
+    		return;
+    	}
+    	if(newProperty == null) {
+    		throw new IllegalArgumentException ("Cannot add a null property");
+    	}
+    	m_propertyMetaData.add(newProperty);
+    }
+
+    /**
+     * Used to set a ServiceMetadata object.
+     *
+     * @param service a ServiceMetadata
+     */
+    public void setService(ServiceMetadata service) {
+    	if(m_validated) {
+    		return;
+    	}
+        m_service = service;
+    }
+
+    /**
+     * Used to add a reference metadata to the component
+     *
+     * @param newReference a new ReferenceMetadata to be added
+     */
+    public void addDependency(ReferenceMetadata newReference) {
+    	if(newReference == null) {
+    		throw new IllegalArgumentException ("Cannot add a null ReferenceMetadata");
+    	}
+        m_references.add(newReference);
+    }
+
+    
+    /////////////////////////////////////////// GETTERS //////////////////////////////////////
+    
+    /**
+     * Returns the name of the component
+     * 
+     * @return A string containing the name of the component 
+     */
+    public String getName() {
+    	return m_name;
+    }
+    
+    /**
+     * Returns the value of the enabled flag 
+     * 
+     * @return a boolean containing the value of the enabled flag
+     */
+    public boolean isEnabled() {
+    	return m_enabled;
+    }
+
+    /**
+     * Returns the factory identifier
+     * 
+     * @return A string containing a factory identifier or null
+     */
+    public String getFactoryIdentifier() {
+    	return m_factory;
+    }
+    
+    /**
+     * Returns the flag that defines the activation policy for the component
+     * 
+     * @return a boolean that defines the activation policy
+     */
+    public boolean isImmediate() {
+    	return m_immediate;
+    }
+    
+    /**
+     * Returns the name of the implementation class
+     *
+     * @return the name of the implementation class
+     */
+    public String getImplementationClassName() {
+        return m_implementationClassName;
+    }
+
+    /**
+     * Returns the associated ServiceMetadata
+     * 
+     * @return a ServiceMetadata object or null if the Component does not provide any service
+     */
+    public ServiceMetadata getServiceMetadata() {
+    	return m_service;
+    }
+
+    /**
+     * Returns the properties.
+     *
+     * @return the properties as a Dictionary
+     */
+    public Dictionary getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * Returns the dependency descriptors
+     *
+     * @return a Collection of dependency descriptors
+     */
+    public List getDependencies() {
+        return m_references;
+    }
+
+    /**
+     * Test to see if this service is a factory
+     *
+     * @return true if it is a factory, false otherwise
+     */
+    public boolean isFactory() {
+        return m_factory != null;
+    }
+    
+    /**
+     * Method used to verify if the semantics of this metadata are correct
+     */
+    void validate() {
+    	
+        // First check if the properties are valid (and extract property values)
+        Iterator propertyIterator = m_propertyMetaData.iterator();
+    	while ( propertyIterator.hasNext() ) {
+    	    PropertyMetadata propMeta = (PropertyMetadata) propertyIterator.next();
+            propMeta.validate();
+            m_properties.put(propMeta.getName(), propMeta.getValue());
+        }
+    	m_propertyMetaData.clear();
+    	
+    	// Check that the provided services are valid too
+    	if(m_service != null) {
+    		m_service.validate();
+    	}
+    	
+    	// Check that the references are ok
+    	Iterator referenceIterator = m_references.iterator();
+    	while ( referenceIterator.hasNext() ) {
+    		((ReferenceMetadata)referenceIterator.next()).validate();
+    	}
+    	    	
+    	// 112.10 The name of the component is required
+    	if( m_name == null ) {
+    		throw new ComponentException("The component name has not been set");
+    	}
+    	
+    	// 112.10 There must be one implementation element and the class atribute is required
+    	if ( m_implementationClassName == null ) {
+    		throw new ComponentException("The implementation class name has not been set for this component");
+    	}
+    	
+    	// 112.2.3 A delayed component specifies a service, is not specified to be a factory component
+    	// and does not have the immediate attribute of the component element set to true.
+    	if(m_immediate == false && m_service == null) {
+    		throw new ComponentException("Component '"+m_name+"' is specified as being delayed but does not provide any service.");
+    	}    	
+    	
+    	if ( m_factory != null && m_immediate == false) {
+    		throw new ComponentException("A factory cannot be a delayed component");
+    	}
+    	
+    	// TODO: 112.4.6 The serviceFactory attribute (of a provided service) must not be true if 
+    	// the component is a factory component or an immediate component
+
+    	
+    	m_validated = true;
+    	// TODO: put a similar flag on the references and the services
+    }
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
index 28d028a..134070c 100644
--- a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
@@ -1,111 +1,111 @@
-/*
- *   Copyright 2006 The Apache Software Foundation
- *
- *   Licensed under the Apache License, Version 2.0 (the "License");
- *   you may not use this file except in compliance with the License.
- *   You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing, software
- *   distributed under the License is distributed on an "AS IS" BASIS,
- *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *   See the License for the specific language governing permissions and
- *   limitations under the License.
- *
- */
-package org.apache.felix.scr;
-
-import org.osgi.service.component.ComponentException;
-
-/**
- * A property descriptor that contains the information for properties
- * defined in the descriptor
- *
- */
-public class PropertyMetadata {
-	
-	// Name of the property (required)
-	private String m_name;
-	
-	// Type of the property (optional)
-	private String m_type = "String";
-	
-	// Value of the type (optional)
-	private Object m_value;
-	
-	// Flag that indicates if this PropertyMetadata has been validated and thus has become immutable
-	private boolean m_validated = false;
-
-	/**
-	 * Set the name
-	 * 
-	 * @param name
-	 */
-	public void setName(String name) {
-		if (m_validated == true) {
-			return;
-		}
-		
-		m_name = name;
-	}
-	
-
-	/**
-	 * Set the type
-	 * 
-	 * @param type
-	 */
-	public void setType(String type) {
-		if (m_validated == true) {
-			return;
-		}
-		m_type = type;
-	}
-		
-	/**
-	 * Set the value
-	 * 
-	 * @param value
-	 */
-	public void setValue(String value) {
-		if (m_validated == true) {
-			return;
-		}
-		
-		// 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
-		// Should the type accept lowercase too?
-		if(m_type.equals("String")) {
-			m_value = String.valueOf(value);
-        }
-		else if(m_type.equals("Long")) {
-			m_value = Long.valueOf(value);
-        }
-		else if(m_type.equals("Double")) {
-			m_value = Double.valueOf(value);
-        }
-		else if(m_type.equals("Float")) {
-			m_value = Float.valueOf(value);
-        }
-		else if(m_type.equals("Integer")) {
-			m_value = Integer.valueOf(value);
-        }
-		else if(m_type.equals("Byte")) {
-			m_value = Byte.valueOf(value);
-        }
-		else if(m_type.equals("Char")) {
-			//TODO: verify if this is adequate for Characters
-			m_value = Byte.valueOf(value);
-        }
-		else if(m_type.equals("Boolean")) {
-			m_value = Boolean.valueOf(value);
-        }
-		else if(m_type.equals("Short")) {
-			m_value = Short.valueOf(value);
-        }
-		else {
-			throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
-		}
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.scr;
+
+import org.osgi.service.component.ComponentException;
+
+/**
+ * A property descriptor that contains the information for properties
+ * defined in the descriptor
+ *
+ */
+public class PropertyMetadata {
+	
+	// Name of the property (required)
+	private String m_name;
+	
+	// Type of the property (optional)
+	private String m_type = "String";
+	
+	// Value of the type (optional)
+	private Object m_value;
+	
+	// Flag that indicates if this PropertyMetadata has been validated and thus has become immutable
+	private boolean m_validated = false;
+
+	/**
+	 * Set the name
+	 * 
+	 * @param name
+	 */
+	public void setName(String name) {
+		if (m_validated == true) {
+			return;
+		}
+		
+		m_name = name;
+	}
+	
+
+	/**
+	 * Set the type
+	 * 
+	 * @param type
+	 */
+	public void setType(String type) {
+		if (m_validated == true) {
+			return;
+		}
+		m_type = type;
+	}
+		
+	/**
+	 * Set the value
+	 * 
+	 * @param value
+	 */
+	public void setValue(String value) {
+		if (m_validated == true) {
+			return;
+		}
+		
+		// 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
+		// Should the type accept lowercase too?
+		if(m_type.equals("String")) {
+			m_value = String.valueOf(value);
+        }
+		else if(m_type.equals("Long")) {
+			m_value = Long.valueOf(value);
+        }
+		else if(m_type.equals("Double")) {
+			m_value = Double.valueOf(value);
+        }
+		else if(m_type.equals("Float")) {
+			m_value = Float.valueOf(value);
+        }
+		else if(m_type.equals("Integer")) {
+			m_value = Integer.valueOf(value);
+        }
+		else if(m_type.equals("Byte")) {
+			m_value = Byte.valueOf(value);
+        }
+		else if(m_type.equals("Char")) {
+			//TODO: verify if this is adequate for Characters
+			m_value = Byte.valueOf(value);
+        }
+		else if(m_type.equals("Boolean")) {
+			m_value = Boolean.valueOf(value);
+        }
+		else if(m_type.equals("Short")) {
+			m_value = Short.valueOf(value);
+        }
+		else {
+			throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
+		}
 	}
 
     /**
@@ -134,14 +134,14 @@
     public Object getValue() {
         return m_value;
     }
-
-    /**
-     * Method used to verify if the semantics of this metadata are correct
-     */
-    public void validate(){
-    	if(m_name == null)
-    	{
-    		throw new ComponentException("Property name attribute is mandatory");
-    	}
+
+    /**
+     * Method used to verify if the semantics of this metadata are correct
+     */
+    public void validate(){
+    	if(m_name == null)
+    	{
+    		throw new ComponentException("Property name attribute is mandatory");
+    	}
     }
-}
+}
