FELIX-4401 Temporarily add runtime spec packages to source

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1602632 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index 9ab6180..7166530 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -27,12 +27,15 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.felix.scr.impl.config.ScrConfiguration;
+import org.apache.felix.scr.impl.runtime.ServiceComponentRuntimeImpl;
 import org.apache.felix.utils.extender.AbstractExtender;
 import org.apache.felix.utils.extender.Extension;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
 
@@ -73,6 +76,8 @@
 
     //  thread acting upon configurations
     private ComponentActorThread m_componentActor;
+    
+    private ServiceRegistration<ServiceComponentRuntime> m_runtime_reg;
 
     public Activator() {
         m_configuration = new ScrConfiguration( this );
@@ -136,7 +141,8 @@
         // prepare component registry
         m_componentBundles = new HashMap<Long, BundleComponentActivator>();
         m_componentRegistry = new ComponentRegistry( m_context );
-
+        ServiceComponentRuntime runtime = new ServiceComponentRuntimeImpl(m_context, m_componentRegistry);
+        m_runtime_reg = m_context.registerService(ServiceComponentRuntime.class, runtime, null);
 
         // log SCR startup
         log( LogService.LOG_INFO, m_bundle, " Version = {0}",
@@ -150,9 +156,10 @@
 
         super.doStart();
 
+        //TODO register runtime.  Possibly register obsolete stuff too.
         // register the Gogo and old Shell commands
-        ScrCommand scrCommand = ScrCommand.register(m_context, m_componentRegistry, m_configuration);
-        m_configuration.setScrCommand( scrCommand );
+//        ScrCommand scrCommand = ScrCommand.register(m_context, m_componentRegistry, m_configuration);
+//        m_configuration.setScrCommand( scrCommand );
     }
     
     public void stop(BundleContext context) throws Exception
@@ -173,7 +180,12 @@
         // stop tracking
         super.doStop();
 
-        // dispose component registry
+    	if (m_runtime_reg != null)
+    	{
+			m_runtime_reg.unregister();
+			m_runtime_reg = null;
+		}
+		// dispose component registry
         m_componentRegistry.dispose();
 
         // terminate the actor thread
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
index bd665f1..a667462 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
@@ -60,7 +60,7 @@
  * registers itself as the {@link ScrService} to support access to the
  * registered components.
  */
-public class ComponentRegistry implements ScrService, ServiceListener
+public class ComponentRegistry implements ServiceListener
 {
 
     // the name of the ConfigurationAdmin service
@@ -84,7 +84,7 @@
      * @see #registerComponentHolder(String, ComponentHolder)
      * @see #unregisterComponentHolder(String)
      */
-    private final Map<ComponentRegistryKey, ComponentHolder> m_componentHoldersByName;
+    private final Map<ComponentRegistryKey, ComponentHolder<?>> m_componentHoldersByName;
 
     /**
      * The map of known components indexed by component configuration pid. The values are
@@ -103,7 +103,7 @@
      * @see #unregisterComponentHolder(String)
      * @see ConfigurationSupport#configurationEvent(org.osgi.service.cm.ConfigurationEvent)
      */
-    private final Map<String, Set<ComponentHolder>> m_componentHoldersByPid;
+    private final Map<String, Set<ComponentHolder<?>>> m_componentHoldersByPid;
 
     /**
      * Map of components by component ID. This map indexed by the component
@@ -137,8 +137,8 @@
     protected ComponentRegistry( BundleContext context )
     {
         m_bundleContext = context;
-        m_componentHoldersByName = new HashMap<ComponentRegistryKey, ComponentHolder>();
-        m_componentHoldersByPid = new HashMap<String, Set<ComponentHolder>>();
+        m_componentHoldersByName = new HashMap<ComponentRegistryKey, ComponentHolder<?>>();
+        m_componentHoldersByPid = new HashMap<String, Set<ComponentHolder<?>>>();
         m_componentsById = new HashMap<Long, AbstractComponentManager<?>>();
 
         // keep me informed on ConfigurationAdmin state changes
@@ -159,11 +159,11 @@
         }
 
         // register as ScrService
-        Dictionary props = new Hashtable();
-        props.put( Constants.SERVICE_DESCRIPTION, "Declarative Services Management Agent" );
-        props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
-        m_registration = context.registerService( new String[]
-            { ScrService.class.getName(), }, this, props );
+//        Dictionary<String, Object> props = new Hashtable<String, Object>();
+//        props.put( Constants.SERVICE_DESCRIPTION, "Declarative Services Management Agent" );
+//        props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
+//        m_registration = context.registerService( new String[]
+//            { ScrService.class.getName(), }, this, props );
     }
 
 
@@ -187,79 +187,79 @@
 
     //---------- ScrService interface
 
-    public Component[] getComponents()
-    {
-        ComponentHolder[] holders = getComponentHolders();
-        ArrayList<Component> list = new ArrayList<Component>();
-        for ( ComponentHolder holder: holders )
-        {
-            if ( holder != null )
-            {
-                list.addAll(holder.getComponents());
-            }
-        }
-
-        // nothing to return
-        if ( list.isEmpty() )
-        {
-            return null;
-        }
-
-        return ( Component[] ) list.toArray( new Component[list.size()] );
-    }
+//    public Component[] getComponents()
+//    {
+//        List<ComponentHolder<?>> holders = getComponentHolders();
+//        ArrayList<Component> list = new ArrayList<Component>();
+//        for ( ComponentHolder holder: holders )
+//        {
+//            if ( holder != null )
+//            {
+//                list.addAll(holder.getComponents());
+//            }
+//        }
+//
+//        // nothing to return
+//        if ( list.isEmpty() )
+//        {
+//            return null;
+//        }
+//
+//        return ( Component[] ) list.toArray( new Component[list.size()] );
+//    }
 
 
-    public Component[] getComponents( Bundle bundle )
-    {
-        ComponentHolder[] holders = getComponentHolders();
-        List<Component> list = new ArrayList<Component>();
-        for ( ComponentHolder<?> holder: holders )
-        {
-            if ( holder != null )
-            {
-                BundleComponentActivator activator = holder.getActivator();
-                if ( activator != null && activator.getBundleContext().getBundle() == bundle )
-                {
-                    list.addAll(holder.getComponents());
-                }
-            }
-        }
-
-        // nothing to return
-        if ( list.isEmpty() )
-        {
-            return null;
-        }
-
-        return list.toArray( new Component[list.size()] );
-    }
+//    public Component[] getComponents( Bundle bundle )
+//    {
+//        List<ComponentHolder<?>> holders = getComponentHolders();
+//        List<Component> list = new ArrayList<Component>();
+//        for ( ComponentHolder<?> holder: holders )
+//        {
+//            if ( holder != null )
+//            {
+//                BundleComponentActivator activator = holder.getActivator();
+//                if ( activator != null && activator.getBundleContext().getBundle() == bundle )
+//                {
+//                    list.addAll(holder.getComponents());
+//                }
+//            }
+//        }
+//
+//        // nothing to return
+//        if ( list.isEmpty() )
+//        {
+//            return null;
+//        }
+//
+//        return list.toArray( new Component[list.size()] );
+//    }
+//
+//
+//    public Component getComponent( long componentId )
+//    {
+//        synchronized ( m_componentsById )
+//        {
+//            return m_componentsById.get( componentId );
+//        }
+//    }
 
 
-    public Component getComponent( long componentId )
-    {
-        synchronized ( m_componentsById )
-        {
-            return m_componentsById.get( componentId );
-        }
-    }
-
-
-    public Component[] getComponents( String componentName )
-    {
-        List<Component> list = new ArrayList<Component>();
-        synchronized ( m_componentHoldersByName )
-        {
-            for ( ComponentHolder<?> c: m_componentHoldersByName.values() )
-            {
-                if ( c.getComponentMetadata().getName().equals( componentName ) )
-                {
-                    list.addAll( c.getComponents() );
-                }
-            }
-        }
-
-        return ( list.isEmpty() ) ? null : list.toArray( new Component[list.size()] );
-    }
+//    public Component[] getComponents( String componentName )
+//    {
+//        List<Component> list = new ArrayList<Component>();
+//        synchronized ( m_componentHoldersByName )
+//        {
+//            for ( ComponentHolder<?> c: m_componentHoldersByName.values() )
+//            {
+//                if ( c.getComponentMetadata().getName().equals( componentName ) )
+//                {
+//                    list.addAll( c.getComponents() );
+//                }
+//            }
+//        }
+//
+//        return ( list.isEmpty() ) ? null : list.toArray( new Component[list.size()] );
+//    }
 
 
     //---------- ComponentManager registration by component Id
@@ -406,10 +406,10 @@
                 // Since several components may refer to the same configuration pid, we have to
                 // store the component holder in a Set, in order to be able to lookup every
                 // components from a given pid.
-                Set<ComponentHolder> set = m_componentHoldersByPid.get( configurationPid );
+                Set<ComponentHolder<?>> set = m_componentHoldersByPid.get( configurationPid );
                 if ( set == null )
                 {
-                    set = new HashSet<ComponentHolder>();
+                    set = new HashSet<ComponentHolder<?>>();
                     m_componentHoldersByPid.put( configurationPid, set );
                 }
                 set.add( componentHolder );
@@ -441,13 +441,13 @@
      * @param pid the pid candidate
      * @return the set of ComponentHolders matching the singleton pid supplied
      */
-    public final Collection<ComponentHolder> getComponentHoldersByPid(TargetedPID targetedPid)
+    public final Collection<ComponentHolder<?>> getComponentHoldersByPid(TargetedPID targetedPid)
     {
         String pid = targetedPid.getServicePid();
-        Set<ComponentHolder> componentHoldersUsingPid = new HashSet<ComponentHolder>();
+        Set<ComponentHolder<?>> componentHoldersUsingPid = new HashSet<ComponentHolder<?>>();
         synchronized (m_componentHoldersByPid)
         {
-            Set<ComponentHolder> set = m_componentHoldersByPid.get(pid);
+            Set<ComponentHolder<?>> set = m_componentHoldersByPid.get(pid);
             // only return the entry if non-null and not a reservation
             if (set != null)
             {
@@ -469,12 +469,36 @@
      * name reservations or {@link ComponentHolder} instances for actual
      * holders of components.
      */
-    private ComponentHolder[] getComponentHolders()
+    public final List<ComponentHolder<?>> getComponentHolders()
     {
+    	List<ComponentHolder<?>> all = new ArrayList<ComponentHolder<?>>();
         synchronized ( m_componentHoldersByName )
         {
-            return m_componentHoldersByName.values().toArray( new ComponentHolder[ m_componentHoldersByName.size() ]);
+        	all.addAll(m_componentHoldersByName.values());
         }
+        return all;
+    }
+
+    public final List<ComponentHolder<?>> getComponentHolders(Bundle...bundles)
+    {
+    	List<ComponentHolder<?>> all =getComponentHolders();
+        List<ComponentHolder<?>> holders = new ArrayList<ComponentHolder<?>>();
+        for ( ComponentHolder<?> holder: all)
+        {
+        	BundleComponentActivator activator = holder.getActivator();
+        	if (activator != null)
+        	{
+        		Bundle holderBundle = activator.getBundleContext().getBundle();
+        		for (Bundle b: bundles)
+        		{
+        			if (b == holderBundle)
+        			{
+        				holders.add(holder);
+        			}
+        		}
+        	}
+        }
+        return holders;
     }
 
 
@@ -498,7 +522,7 @@
      */
     final void unregisterComponentHolder( final ComponentRegistryKey key )
     {
-        ComponentHolder component;
+        ComponentHolder<?> component;
         synchronized ( m_componentHoldersByName )
         {
             component = m_componentHoldersByName.remove( key );
@@ -513,7 +537,7 @@
                 List<String> configurationPids = component.getComponentMetadata().getConfigurationPid();
                 for ( String configurationPid: configurationPids )
                 {
-                    Set<ComponentHolder> componentsForPid = m_componentHoldersByPid.get( configurationPid );
+                    Set<ComponentHolder<?>> componentsForPid = m_componentHoldersByPid.get( configurationPid );
                     if ( componentsForPid != null )
                     {
                         componentsForPid.remove( component );
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
index d91bd49..d2e3722 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
@@ -61,14 +61,15 @@
      * Configuration Admin service.
      *
      * @param pid The PID of the deleted configuration
+     * @param factoryPid TODO
      */
-    void configurationDeleted( String pid );
+    void configurationDeleted( TargetedPID pid, TargetedPID factoryPid );
 
 
     /**
      * Configure a component with configuration from the given PID.
      * @param targetedPid Targeted PID for the configuration
-     * @param factoryTargetedPid TODO
+     * @param factoryTargetedPid the (targeted) factory pid or null for a singleton pid
      * @param props the property dictionary from the configuration.
      * @param changeCount change count of the configuration, or R4 imitation.
      *
@@ -79,10 +80,11 @@
     
     /**
      * Change count (or fake R4 imitation)
-     * @param pid PID of the component we are interested in.
+     * @param pid a PID for the component we are interested in.
+     * @param targetedPid For a singleton pid, same as "pid"; for a factory pid, the factory pid.
      * @return the last change count from a configurationUpdated call for the given pid.
      */
-    long getChangeCount( TargetedPID pid );
+    long getChangeCount( TargetedPID pid, TargetedPID targetedPid );
     
     /**
      * Returns the targeted PID used to configure this component
@@ -95,7 +97,7 @@
     /**
      * Returns all <code>Component</code> instances held by this holder.
      */
-    List<? extends Component> getComponents();
+    List<? extends ComponentManager<?>> getComponents();
 
     /**
      * Enables all components of this holder and if satisifed activates
@@ -114,6 +116,12 @@
      *      asynchronously or not.
      */
     void disableComponents( boolean async );
+    
+    /**
+     * whether the component is currently enabled
+     * @return whether the component is enabled
+     */
+    boolean isEnabled();
 
 
     /**
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentManager.java
new file mode 100644
index 0000000..f773090
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentManager.java
@@ -0,0 +1,27 @@
+package org.apache.felix.scr.impl.config;
+
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+
+
+public interface ComponentManager<S> {
+	
+	int STATE_SATISFIED = ComponentConfigurationDTO.SATISFIED;
+	int STATE_UNSATISFIED = ComponentConfigurationDTO.UNSATISFIED;
+	int STATE_ACTIVE = ComponentConfigurationDTO.ACTIVE;
+	int STATE_FACTORY = 8;
+	int STATE_FACTORY_INSTANCE = 16;
+	int STATE_DISPOSED = 32;
+	int STATE_DISABLED = 64; //TODO????
+
+	Map<String, Object> getProperties();
+
+	long getId();
+
+	int getState();
+	
+	List<? extends ReferenceManager<S, ?>> getReferenceManagers();
+	
+}
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
index 2e51102..5aa27ed 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurableComponentHolder.java
@@ -74,9 +74,9 @@
     /** the targeted pids corresponding to the pids specified in the config metadata, except possibly for the single 
      * factory pid
      */
-    private final List<TargetedPID> m_targetedPids;
+    private final TargetedPID[] m_targetedPids;
     
-    private final List<Long> m_changeCount;
+    private final Long[] m_changeCount;
     
     private final Map<String, Long> m_factoryChangeCount = new HashMap<String, Long>();
     
@@ -89,7 +89,7 @@
     /**
      * the non-factory configurations shared between all instances.
      */
-    private final List<Dictionary<String, Object>> m_configurations;
+    private final Dictionary<String, Object>[] m_configurations;
 
     /**
      * the factory configurations indexed by pid (which cannot be a TargetedPID since it's generated by CA).  We have to track these since
@@ -143,15 +143,9 @@
         this.m_activator = activator;
         this.m_componentMetadata = metadata;
         int pidCount = metadata.getConfigurationPid().size();
-		this.m_targetedPids = new ArrayList<TargetedPID>(pidCount);
-        this.m_configurations = new ArrayList<Dictionary<String, Object>>(pidCount);
-        this.m_changeCount = new ArrayList<Long>(pidCount);
-        for (int i = 0; i < pidCount; i++)
-        {
-        	m_targetedPids.add(null);
-        	m_configurations.add(null);
-        	m_changeCount.add(null);
-        }
+		this.m_targetedPids = new TargetedPID[pidCount];
+        this.m_configurations = new Dictionary[pidCount];
+        this.m_changeCount = new Long[pidCount];
         this.m_components = new HashMap<String, SingleComponentManager<S>>();
         this.m_componentMethods = new ComponentMethods();
         this.m_enabled = false;
@@ -182,6 +176,10 @@
             manager = new SingleComponentManager<S>( m_activator, this, m_componentMetadata, m_componentMethods );
         }
 
+        if ( m_enabled )
+        {
+        	manager.enable( false );
+        }
         return manager;
     }
 
@@ -218,75 +216,67 @@
      * simply disposed off and removed from the internal map.</li>
      * </ul>
      */
-    public void configurationDeleted( final String pid )
+    public void configurationDeleted( final TargetedPID pid, TargetedPID factoryPid )
     {
         log( LogService.LOG_DEBUG, "ImmediateComponentHolder configuration deleted for pid {0}",
                 new Object[] {pid}, null);
 
         // component to deconfigure or dispose of
-        final SingleComponentManager icm;
+        final SingleComponentManager<S> icm;
         boolean deconfigure = false;
 
         synchronized ( m_components )
         {
-            // FELIX-2231: nothing to do any more, all components have been disposed off
-            if (m_singleComponent == null) 
-            {
-                return;
-            }
-
-            if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
-            {
-                // singleton configuration has pid equal to component name
-                icm = m_singleComponent;
-                deconfigure = true;
-            }
-            else
-            {
-                // remove the component configured with the deleted configuration
-                icm = m_components.remove( pid );
-                if ( icm == null ) 
-                {
-                    // we already removed the component with the deleted configuration
-                    return;
-                }
-
-                // special casing if the single component is deconfigured
-                if ( m_singleComponent == icm )
-                {
-
-                    // if the single component is the last remaining, deconfig
-                    if ( m_components.isEmpty() )
-                    {
-
-                        // if the single component is the last remaining
-                        // deconfigure it
-		                deconfigure = true;
-
-                    }
-                    else
-                    {
-
-                        // replace the single component field with another
-                        // entry from the map
-                        m_singleComponent = m_components.values().iterator().next();
-
-                    }
-                }
-            }
+//            // FELIX-2231: nothing to do any more, all components have been disposed off
+//            if (m_singleComponent == null) 
+//            {
+//                return;
+//            }
+			if (factoryPid != null) {
+				checkFactoryPidIndex(factoryPid);
+				String servicePid = pid.getServicePid();
+				icm = m_components.remove(servicePid);
+				if (icm == null)
+				{
+					return;
+				}
+				m_factoryTargetedPids.remove(servicePid);
+				m_factoryChangeCount.remove(servicePid);
+				m_factoryConfigurations.remove(servicePid);
+				deconfigure = m_componentMetadata.isConfigurationOptional() && m_components.isEmpty();
+				if ( deconfigure )
+				{
+					m_singleComponent = icm;
+				}
+				if ( m_components.isEmpty() )
+				{
+					m_factoryPidIndex = null;
+				}
+			}
+			else
+			{
+				//singleton pid
+				int index = getSingletonPidIndex(pid);
+				m_targetedPids[index] = null;
+				m_changeCount[index] = null;
+				m_configurations[index] = null;
+				icm = m_singleComponent;
+				deconfigure = m_componentMetadata.isConfigurationOptional();
+				if ( !deconfigure )
+				{
+					m_singleComponent = null;
+				}
+			}
         }
 
-        // icm may be null if the last configuration deleted was the
-        // single component's configuration. Otherwise the component
-        // is not the "last" and has to be disposed off
-        if ( deconfigure )
+        if ( icm != null ) 
         {
-	        icm.reconfigure( null );
-        }
-        else
-        {
-            icm.dispose( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
-        }
+			if ( deconfigure ) {
+				icm.reconfigure(null);
+			} else {
+				icm.dispose(ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED);
+			}
+		}
     }
 
 
@@ -310,7 +300,7 @@
                 new Object[] {pid, props}, null);
 
         // component to update or create
-        final SingleComponentManager scm;
+        final SingleComponentManager<S> scm;
         final String message;
         Object[] notEnabledArguments = null;
         boolean created = false;
@@ -320,34 +310,7 @@
         synchronized (m_components) {
 			//Find or create the component manager, or return if not satisfied.
 			if (factoryPid != null) {
-				int index = m_componentMetadata.getPidIndex(factoryPid);
-				if (index == -1) {
-					log(LogService.LOG_ERROR,
-							"Unrecognized factory pid {0], expected one of {1}",
-							new Object[] { factoryPid,
-									m_componentMetadata.getConfigurationPid() },
-							null);
-					throw new IllegalArgumentException(
-							"Unrecognized factory pid " + factoryPid);
-				}
-				if (m_configurations.get(index) != null) {
-					log(LogService.LOG_ERROR,
-							"factory pid {0], but this pids already supplied as a singleton: {1}",
-							new Object[] { factoryPid, m_targetedPids }, null);
-					throw new IllegalStateException(
-							"Factory pid supplied after all non-factory configurations supplied "
-									+ factoryPid);
-				}
-				if (m_factoryPidIndex == null) {
-					m_factoryPidIndex = index;
-				} else if (index != m_factoryPidIndex) {
-					log(LogService.LOG_ERROR,
-							"factory pid {0] supplied for index {1}, but a factory pid previously supplied at index {2}",
-							new Object[] { factoryPid, index, m_factoryPidIndex },
-							null);
-					throw new IllegalStateException(
-							"Factory pid supplied at wrong index " + factoryPid);
-				}
+				checkFactoryPidIndex(factoryPid);
 				m_factoryConfigurations.put(pid.getServicePid(), props);
 				m_factoryTargetedPids.put(pid.getServicePid(), factoryPid);
 				m_factoryChangeCount.put(pid.getServicePid(), changeCount);
@@ -369,27 +332,10 @@
 
 			} else {
 				//singleton pid
-				int index = m_componentMetadata.getPidIndex(pid);
-				if (index == -1) {
-					log(LogService.LOG_ERROR,
-							"Unrecognized pid {0], expected one of {1}",
-							new Object[] { pid,
-									m_componentMetadata.getConfigurationPid() },
-							null);
-					throw new IllegalArgumentException("Unrecognized pid "
-							+ pid);
-				}
-				if (m_factoryPidIndex != null && index == m_factoryPidIndex) {
-					log(LogService.LOG_ERROR,
-							"singleton pid {0] supplied, but matches an existing factory pid at index: {1}",
-							new Object[] { pid, m_factoryPidIndex }, null);
-					throw new IllegalStateException(
-							"Singleton pid supplied matching a previous factory pid "
-									+ pid);
-				}
-				m_targetedPids.set(index, pid);
-				m_changeCount.set(index, changeCount);
-				m_configurations.set(index, props);
+				int index = getSingletonPidIndex(pid);
+				m_targetedPids[index] = pid;
+				m_changeCount[index] = changeCount;
+				m_configurations[index] = props;
 				if (isSatisfied()) {
 					if (m_singleComponent != null) {
 						scm = m_singleComponent;
@@ -403,17 +349,16 @@
 				}
 
 			}
-			properties = new HashMap<String, Object>();
-			copyTo(properties, m_componentMetadata.getProperties());
-			for (int i = 0; i < m_configurations.size(); i++)
+			properties = new HashMap<String, Object>(m_componentMetadata.getProperties());
+			for (int i = 0; i < m_configurations.length; i++)
 			{
 				if ( m_factoryPidIndex != null && i == m_factoryPidIndex)
 				{
 					copyTo(properties, props);
 				}
-				else if ( m_configurations.get(i) != null )
+				else if ( m_configurations[i] != null )
 				{
-					copyTo(properties, m_configurations.get(i));
+					copyTo(properties, m_configurations[i]);
 				}
 			}
 			
@@ -502,6 +447,60 @@
         return created;
     }
 
+	private int getSingletonPidIndex(TargetedPID pid) {
+		int index = m_componentMetadata.getPidIndex(pid);
+		if (index == -1) {
+			log(LogService.LOG_ERROR,
+					"Unrecognized pid {0], expected one of {1}",
+					new Object[] { pid,
+							m_componentMetadata.getConfigurationPid() },
+					null);
+			throw new IllegalArgumentException("Unrecognized pid "
+					+ pid);
+		}
+		if (m_factoryPidIndex != null && index == m_factoryPidIndex) {
+			log(LogService.LOG_ERROR,
+					"singleton pid {0] supplied, but matches an existing factory pid at index: {1}",
+					new Object[] { pid, m_factoryPidIndex }, null);
+			throw new IllegalStateException(
+					"Singleton pid supplied matching a previous factory pid "
+							+ pid);
+		}
+		return index;
+	}
+
+    //TODO update error messages so they make sense for deleting config too. 
+	private void checkFactoryPidIndex(TargetedPID factoryPid) {
+		int index = m_componentMetadata.getPidIndex(factoryPid);
+		if (index == -1) {
+			log(LogService.LOG_ERROR,
+					"Unrecognized factory pid {0], expected one of {1}",
+					new Object[] { factoryPid,
+							m_componentMetadata.getConfigurationPid() },
+					null);
+			throw new IllegalArgumentException(
+					"Unrecognized factory pid " + factoryPid);
+		}
+		if (m_configurations[index] != null) {
+			log(LogService.LOG_ERROR,
+					"factory pid {0], but this pids already supplied as a singleton: {1}",
+					new Object[] { factoryPid, m_targetedPids }, null);
+			throw new IllegalStateException(
+					"Factory pid supplied after all non-factory configurations supplied "
+							+ factoryPid);
+		}
+		if (m_factoryPidIndex == null) {
+			m_factoryPidIndex = index;
+		} else if (index != m_factoryPidIndex) {
+			log(LogService.LOG_ERROR,
+					"factory pid {0] supplied for index {1}, but a factory pid previously supplied at index {2}",
+					new Object[] { factoryPid, index, m_factoryPidIndex },
+					null);
+			throw new IllegalStateException(
+					"Factory pid supplied at wrong index " + factoryPid);
+		}
+	}
+
     protected static void copyTo( Map<String, Object> target, Dictionary<String, ?> source )
     {
     	
@@ -522,10 +521,9 @@
     	{
     		return true;
     	}
-    	boolean satisfied = true;
     	for ( int i = 0; i < m_componentMetadata.getConfigurationPid().size(); i++)
     	{
-    		if ( m_configurations.get(i) != null)
+    		if ( m_configurations[i] != null)
     		{
     			continue;
     		}
@@ -540,11 +538,12 @@
 
     /**
      * @param pid the Targeted PID we need the change count for
+     * @param targetedPid the targeted factory pid for a factory configuration or the pid for a singleton configuration
      * @return pid for this service pid.
      */
-	public long getChangeCount( TargetedPID pid)
+	public long getChangeCount( TargetedPID pid, TargetedPID targetedPid)
     {
-		int index = m_componentMetadata.getPidIndex(pid);
+		int index = m_componentMetadata.getPidIndex(targetedPid);
 		Long result;
 		if ( index == -1 )
 		{
@@ -556,13 +555,13 @@
 		}
 		else
 		{
-			result = m_changeCount.get(index);
+			result = m_changeCount[index];
 		}
 		return result == null? -1: result;
 		
     }
 
-    public List<? extends Component> getComponents()
+    public List<? extends ComponentManager<?>> getComponents()
     {
         synchronized ( m_components )
         {
@@ -571,6 +570,10 @@
     }
 
 
+	public boolean isEnabled() {
+		return m_enabled;
+	}
+
     public void enableComponents( final boolean async )
     {
     	List<SingleComponentManager<S>> cms;
@@ -619,21 +622,21 @@
         {
             cms = getComponentManagers( true );
         }
-        for ( SingleComponentManager cm : cms )
+        for ( SingleComponentManager<S> cm : cms )
         {
             cm.dispose( reason );
         }
     }
 
 
-    public void disposed( SingleComponentManager component )
+    public void disposed( SingleComponentManager<S> component )
     {
         // ensure the component is removed from the components map
         synchronized ( m_components )
         {
             if ( !m_components.isEmpty() )
             {
-                for ( Iterator vi = m_components.values().iterator(); vi.hasNext(); )
+                for ( Iterator<SingleComponentManager<S>> vi = m_components.values().iterator(); vi.hasNext(); )
                 {
                     if ( component == vi.next() )
                     {
@@ -643,20 +646,9 @@
                 }
             }
 
-            // if the component is the single component, we have to replace it
-            // by another entry in the map
             if ( component == m_singleComponent )
             {
-                if ( m_components.isEmpty() )
-                {
-                    // now what ??
-                    // is it correct to create a new manager ???
-                    m_singleComponent = createComponentManager();
-                }
-                else
-                {
-                    m_singleComponent = m_components.values().iterator().next();
-                }
+            	m_singleComponent = null;
             }
         }
     }
@@ -681,7 +673,7 @@
             return false;
         }
 
-        ConfigurableComponentHolder other = (ConfigurableComponentHolder) object;
+        ConfigurableComponentHolder<S> other = (ConfigurableComponentHolder<S>) object;
         return m_activator == other.m_activator
                 && getName().equals(other.getName());
     }
@@ -774,7 +766,7 @@
     		int index = m_componentMetadata.getPidIndex(pid);
     		if (index != -1)
     		{
-    			return m_targetedPids.get(index);
+    			return m_targetedPids[index];
     		}
     		return null;
     	}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
index f6081e6..8d59979 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
@@ -19,19 +19,13 @@
 package org.apache.felix.scr.impl.config;
 
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.text.MessageFormat;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.felix.scr.impl.Activator;
 import org.apache.felix.scr.impl.BundleComponentActivator;
@@ -58,7 +52,7 @@
         ChangeCount cc = null;
         try
         {
-            Configuration.class.getMethod( "getChangeCount", null );
+            Configuration.class.getMethod( "getChangeCount", (Class<?>[]) null );
             cc = new R5ChangeCount();
         }
         catch ( SecurityException e )
@@ -78,14 +72,14 @@
     private final ComponentRegistry m_registry;
 
     // the service m_registration of the ConfigurationListener service
-    private ServiceRegistration m_registration;
+    private ServiceRegistration<?> m_registration;
     
     public ConfigurationSupport(final BundleContext bundleContext, final ComponentRegistry registry)
     {
         this.m_registry = registry;
 
         // register as listener for configurations
-        Dictionary props = new Hashtable();
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(Constants.SERVICE_DESCRIPTION, "Declarative Services Configuration Support Listener");
         props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
         this.m_registration = bundleContext.registerService(new String[]
@@ -103,7 +97,7 @@
 
     // ---------- BaseConfigurationSupport overwrites
 
-    public boolean configureComponentHolder(final ComponentHolder holder)
+    public boolean configureComponentHolder(final ComponentHolder<?> holder)
     {
 
         // 112.7 configure unless configuration not required
@@ -246,7 +240,7 @@
 
         // iterate over all components which must be configured with this pid
         // (since DS 1.2, components may specify a specific configuration PID (112.4.4 configuration-pid)
-        Collection<ComponentHolder> holders;
+        Collection<ComponentHolder<?>> holders;
 
         if (factoryPid == null)
         {
@@ -261,7 +255,7 @@
                 new Object[] {getEventType(event), pid, holders},
                 null);
 
-        for  ( ComponentHolder componentHolder: holders )
+        for  ( ComponentHolder<?> componentHolder: holders )
         {
             if (!componentHolder.getComponentMetadata().isConfigurationIgnored())
             {
@@ -269,7 +263,7 @@
                 case ConfigurationEvent.CM_DELETED:
                     if ( factoryPid != null || !configureComponentHolder( componentHolder ) )
                     {
-                        componentHolder.configurationDeleted( pid.getServicePid() );
+                        componentHolder.configurationDeleted( pid, factoryPid );
                     }
                     break;
 
@@ -291,13 +285,13 @@
                     TargetedPID oldTargetedPID = componentHolder.getConfigurationTargetedPID(pid, factoryPid);
                     if ( factoryPid != null || targetedPid.equals(oldTargetedPID) || targetedPid.bindsStronger( oldTargetedPID ))
                     {
-                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, componentHolder, bundleContext );
+                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, targetedPid, componentHolder, bundleContext );
                         if ( checkBundleLocation( configInfo.getBundleLocation(), bundleContext.getBundle() ) )
                         {
                             //If this is replacing a weaker targetedPID delete the old one.
                             if ( factoryPid == null && !targetedPid.equals(oldTargetedPID) && oldTargetedPID != null)
                             {
-                                componentHolder.configurationDeleted( pid.getServicePid() );
+                                componentHolder.configurationDeleted( pid, factoryPid );
                             }
                             componentHolder.configurationUpdated( pid, factoryPid, configInfo.getProps(), configInfo.getChangeCount() );
                         }
@@ -326,7 +320,7 @@
                     {
                         //this sets the location to this component's bundle if not already set.  OK here
                         //since it used to be set to this bundle, ok to reset it
-                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, componentHolder, bundleContext );
+                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, targetedPid, componentHolder, bundleContext );
                         Activator.log(LogService.LOG_DEBUG, null, "LocationChanged event, same targetedPID {0}, location now {1}",
                                 new Object[] {targetedPid, configInfo.getBundleLocation()},
                                 null);
@@ -339,7 +333,7 @@
                         if (!checkBundleLocation( configInfo.getBundleLocation(), bundleContext.getBundle() ))
                         {
                             //no, delete it
-                            componentHolder.configurationDeleted( pid.getServicePid() );
+                            componentHolder.configurationDeleted( pid, factoryPid );
                             //maybe there's another match
                             configureComponentHolder(componentHolder);
                             
@@ -352,7 +346,7 @@
                     {
                         //this sets the location to this component's bundle if not already set.  OK here
                         //because if it is set to this bundle we will use it.
-                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, componentHolder, bundleContext );
+                        final ConfigurationInfo configInfo = getConfigurationInfo( pid, targetedPid, componentHolder, bundleContext );
                         Activator.log(LogService.LOG_DEBUG, null, "LocationChanged event, better targetedPID {0} compared to {1}, location now {2}",
                                 new Object[] {targetedPid, oldTargetedPID, configInfo.getBundleLocation()},
                                 null);
@@ -367,7 +361,7 @@
                             if ( oldTargetedPID != null )
                             {
                                 //this is a better match, delete old before setting new
-                                componentHolder.configurationDeleted( pid.getServicePid() );
+                                componentHolder.configurationDeleted( pid, factoryPid );
                             }
                             componentHolder.configurationUpdated( pid, factoryPid,
                                     configInfo.getProps(), configInfo.getChangeCount() );
@@ -448,12 +442,13 @@
      * are ungot.  Extracting the info we need into "configInfo" solves this problem.
      * 
      * @param pid TargetedPID for the desired configuration
+     * @param targetedPid the targeted factory pid for a factory configuration or the pid for a singleton configuration
      * @param componentHolder ComponentHolder that holds the old change count (for r4 fake change counting)
      * @param bundleContext BundleContext to get the CA from
      * @return ConfigurationInfo object containing the info we need from the configuration.
      */
-    private ConfigurationInfo getConfigurationInfo(final TargetedPID pid, ComponentHolder componentHolder,
-            final BundleContext bundleContext)
+    private ConfigurationInfo getConfigurationInfo(final TargetedPID pid, TargetedPID targetedPid,
+            ComponentHolder<?> componentHolder, final BundleContext bundleContext)
     {
         final ServiceReference caRef = bundleContext
             .getServiceReference(ComponentRegistry.CONFIGURATION_ADMIN);
@@ -471,7 +466,7 @@
                             final ConfigurationAdmin ca = ( ConfigurationAdmin ) cao;
                             final Configuration config = getConfiguration( ca, pid.getRawPid() );
                             return new ConfigurationInfo(config.getProperties(), config.getBundleLocation(),
-                                    changeCounter.getChangeCount( config, true, componentHolder.getChangeCount( pid ) ) );
+                                    changeCounter.getChangeCount( config, true, componentHolder.getChangeCount( pid, targetedPid ) ) );
                         }
                         else
                         {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java
new file mode 100644
index 0000000..1bd963a
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ReferenceManager.java
@@ -0,0 +1,30 @@
+package org.apache.felix.scr.impl.config;
+
+import java.util.List;
+
+import org.osgi.framework.ServiceReference;
+
+public interface ReferenceManager<S, T> {
+
+	/**
+	 * Returns an array of <code>ServiceReference</code> instances of all
+	 * services this instance is bound to or <code>null</code> if no services
+	 * are actually bound.
+	 */
+	List<ServiceReference<?>> getServiceReferences();
+
+	/**
+	 * Returns the name of the service reference.
+	 */
+	String getName();
+
+	/**
+	 * Returns the target filter of this dependency as a string or
+	 * <code>null</code> if this dependency has no target filter set.
+	 *
+	 * @return The target filter of this dependency or <code>null</code> if
+	 *      none is set.
+	 */
+	String getTarget();
+
+}
\ No newline at end of file
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java
index 03e97fb..f426cc6 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java
@@ -45,7 +45,7 @@
      * Creates a wrapper for the given delegate dictionary providing read
      * only access to the data.
      */
-    public ReadOnlyDictionary( final Dictionary<S, T> delegate )
+    public ReadOnlyDictionary( final Map<S, T> delegate )
     {
         if ( delegate instanceof Hashtable )
         {
@@ -54,10 +54,9 @@
         else
         {
             this.m_delegate = new Hashtable<S, T>();
-            for ( Enumeration<S> ke = delegate.keys(); ke.hasMoreElements(); )
+            for ( Map.Entry<S, T> entry: delegate.entrySet() )
             {
-                S key = ke.nextElement();
-                this.m_delegate.put( key, delegate.get( key ) );
+                this.m_delegate.put( entry.getKey(), entry.getValue() );
             }
         }
     }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index f952c51..0c551e2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -24,26 +24,26 @@
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
-import org.apache.felix.scr.Component;
-import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.impl.Activator;
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.config.ComponentManager;
+import org.apache.felix.scr.impl.config.ReferenceManager;
 import org.apache.felix.scr.impl.config.ScrConfiguration;
 import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.helper.MethodResult;
@@ -54,7 +54,6 @@
 import org.apache.felix.scr.impl.metadata.ServiceMetadata.Scope;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
@@ -67,7 +66,7 @@
  * implementation object's lifecycle.
  *
  */
-public abstract class AbstractComponentManager<S> implements Component, SimpleLogger
+public abstract class AbstractComponentManager<S> implements SimpleLogger, ComponentManager<S>
 {
     //useful text for deactivation reason numbers
     static final String[] REASONS = {"Unspecified",
@@ -388,20 +387,20 @@
     //---------- Asynchronous frontend to state change methods ----------------
     private static final AtomicLong taskCounter = new AtomicLong( );
 
-    /**
-     * Enables this component and - if satisfied - also activates it. If
-     * enabling the component fails for any reason, the component ends up
-     * disabled.
-     * <p>
-     * This method ignores the <i>enabled</i> flag of the component metadata
-     * and just enables as requested.
-     * <p>
-     * This method enables and activates the component immediately.
-     */
-    public final void enable()
-    {
-        enable( true );
-    }
+//    /**
+//     * Enables this component and - if satisfied - also activates it. If
+//     * enabling the component fails for any reason, the component ends up
+//     * disabled.
+//     * <p>
+//     * This method ignores the <i>enabled</i> flag of the component metadata
+//     * and just enables as requested.
+//     * <p>
+//     * This method enables and activates the component immediately.
+//     */
+//    public final void enable()
+//    {
+//        enable( true );
+//    }
 
 
     public final void enable( final boolean async )
@@ -645,17 +644,6 @@
         return m_componentMetadata.getFactoryIdentifier();
     }
 
-    public Reference[] getReferences()
-    {
-        if ( m_dependencyManagers != null && m_dependencyManagers.size() > 0 )
-        {
-            return (Reference[]) m_dependencyManagers.toArray(
-                    new Reference[m_dependencyManagers.size()] );
-        }
-
-        return null;
-    }
-
     public boolean isImmediate()
     {
         return m_componentMetadata.isImmediate();
@@ -782,7 +770,7 @@
                     null );
             return;
         }
-        if ( !isEnabled())
+        if ( !isInternalEnabled())
         {
             log( LogService.LOG_DEBUG, "Component is not enabled; not activating component",
                     null );
@@ -829,7 +817,7 @@
                         null );
                 return;
             }
-            if ( !isEnabled() )
+            if ( !isInternalEnabled() )
             {
                 log( LogService.LOG_DEBUG, "Component is not enabled; not activating component",
                         null );
@@ -1259,7 +1247,7 @@
         return depMgrList;
     }
 
-    final void updateTargets(Dictionary<String, Object> properties)
+    final void updateTargets(Map<String, Object> properties)
     {
         for ( DependencyManager<S, ?> dm: getDependencyManagers() )
         {
@@ -1312,6 +1300,11 @@
     {
         return m_dependencyManagers;
     }
+    
+    public List<? extends ReferenceManager<S, ?>> getReferenceManagers()
+    {
+    	return m_dependencyManagers;
+    }
 
     /**
      * Returns an iterator over the {@link DependencyManager} objects
@@ -1327,11 +1320,11 @@
 
     DependencyManager<S, ?> getDependencyManager(String name)
     {
-        for ( DependencyManager<S, ?> dm: getDependencyManagers() )
+        for ( ReferenceManager<S, ?> dm: getDependencyManagers() )
         {
             if ( name.equals(dm.getName()) )
             {
-                return dm;
+                return (DependencyManager<S, ?>) dm;
             }
         }
 
@@ -1360,7 +1353,10 @@
 
     public abstract boolean hasConfiguration();
 
-    public abstract Dictionary<String, Object> getProperties();
+    /* (non-Javadoc)
+	 * @see org.apache.felix.scr.impl.manager.ComponentManager#getProperties()
+	 */
+    public abstract Map<String, Object> getProperties();
 
     public abstract void setServiceProperties( Dictionary<String, Object> serviceProperties );
 
@@ -1377,25 +1373,6 @@
 
     /**
      * Copies the properties from the <code>source</code> <code>Dictionary</code>
-     * into the <code>target</code> <code>Dictionary</code>.
-     *
-     * @param target The <code>Dictionary</code> into which to copy the
-     *      properties. If <code>null</code> a new <code>Hashtable</code> is
-     *      created.
-     * @param source The <code>Dictionary</code> providing the properties to
-     *      copy. If <code>null</code> or empty, nothing is copied.
-     *
-     * @return The <code>target</code> is returned, which may be empty if
-     *      <code>source</code> is <code>null</code> or empty and
-     *      <code>target</code> was <code>null</code>.
-     */
-    protected static Dictionary<String, Object> copyTo( Dictionary<String, Object> target, Dictionary<String, ?> source )
-    {
-        return copyTo( target, source, true );
-    }
-
-    /**
-     * Copies the properties from the <code>source</code> <code>Dictionary</code>
      * into the <code>target</code> <code>Dictionary</code> except for private
      * properties (whose name has a leading dot) which are only copied if the
      * <code>allProps</code> parameter is <code>true</code>.
@@ -1413,7 +1390,7 @@
      *         <code>target</code> was <code>null</code> or all properties are
      *         private and had not to be copied
      */
-    protected static Dictionary<String, Object> copyTo( Dictionary<String, Object> target, final Dictionary<String, ?> source, final boolean allProps )
+    protected static Dictionary<String, Object> copyTo( Dictionary<String, Object> target, final Map<String, ?> source, final boolean allProps )
     {
         if ( target == null )
         {
@@ -1422,10 +1399,65 @@
 
         if ( source != null && !source.isEmpty() )
         {
-            for ( Enumeration ce = source.keys(); ce.hasMoreElements(); )
+            for ( Map.Entry<String, ?> entry: source.entrySet() )
             {
                 // cast is save, because key must be a string as per the spec
-                String key = ( String ) ce.nextElement();
+                String key = entry.getKey();
+                if ( allProps || key.charAt( 0 ) != '.' )
+                {
+                    target.put( key, entry.getValue() );
+                }
+            }
+        }
+
+        return target;
+    }
+
+    /**
+     * Copies the properties from the <code>source</code> <code>Dictionary</code>
+     * into the <code>target</code> <code>Dictionary</code> except for private
+     * properties (whose name has a leading dot) which are only copied if the
+     * <code>allProps</code> parameter is <code>true</code>.
+     * @param source    The <code>Dictionary</code> providing the properties to
+     *                  copy. If <code>null</code> or empty, nothing is copied.
+     * @param allProps  Whether all properties (<code>true</code>) or only the
+     *                  public properties (<code>false</code>) are to be copied.
+     *
+     * @return The <code>target</code> is returned, which may be empty if
+     *         <code>source</code> is <code>null</code> or empty and
+     *         <code>target</code> was <code>null</code> or all properties are
+     *         private and had not to be copied
+     */
+    protected static Map<String, Object> copyToMap( final Dictionary<String, ?> source, final boolean allProps )
+    {
+        Map<String, Object> target = new HashMap<String, Object>();
+
+        if ( source != null && !source.isEmpty() )
+        {
+            for ( Enumeration<String> ce = source.keys(); ce.hasMoreElements(); )
+            {
+                // cast is save, because key must be a string as per the spec
+                String key = ce.nextElement();
+                if ( allProps || key.charAt( 0 ) != '.' )
+                {
+                    target.put( key, source.get( key ) );
+                }
+            }
+        }
+
+        return target;
+    }
+
+    protected static Dictionary<String, Object> copyToDictionary( final Dictionary<String, ?> source, final boolean allProps )
+    {
+        Hashtable<String, Object> target = new Hashtable<String, Object>();
+
+        if ( source != null && !source.isEmpty() )
+        {
+            for ( Enumeration<String> ce = source.keys(); ce.hasMoreElements(); )
+            {
+                // cast is save, because key must be a string as per the spec
+                String key = ce.nextElement();
                 if ( allProps || key.charAt( 0 ) != '.' )
                 {
                     target.put( key, source.get( key ) );
@@ -1445,29 +1477,32 @@
         return m_componentMetadata;
     }
 
+    /**
+     * TODO now returning bizarre mix of values!!
+     */
     public int getState()
     {
         if (m_disposed)
         {
-            return Component.STATE_DISPOSED;
+            return STATE_DISPOSED;
         }
         if ( !m_internalEnabled)
         {
-            return Component.STATE_DISABLED;
+            return STATE_DISABLED;
         }
         if ( getServiceRegistration() == null && (getProvidedServices() != null || !hasInstance()))
         {
-            return Component.STATE_UNSATISFIED;
+            return STATE_UNSATISFIED;
         }
         if ( isFactory() && !m_factoryInstance )
         {
-            return Component.STATE_FACTORY;
+            return STATE_FACTORY;
         }
         if ( hasInstance() )
         {
-            return Component.STATE_ACTIVE;
+            return STATE_ACTIVE;
         }
-        return Component.STATE_REGISTERED;
+        return STATE_SATISFIED;
     }
 
     abstract boolean hasInstance();
@@ -1481,7 +1516,7 @@
         }
     }
 
-    boolean isEnabled()
+    boolean isInternalEnabled()
     {
         return m_internalEnabled;
     }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
index 0ead123..9a1db51 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
@@ -89,8 +89,7 @@
     public final Dictionary<String, Object> getProperties()
     {
         // 112.12.3.5 The Dictionary is read-only and cannot be modified
-        Dictionary<String, Object> ctxProperties = m_componentManager.getProperties();
-        return new ReadOnlyDictionary<String, Object>( ctxProperties );
+        return new ReadOnlyDictionary<String, Object>( m_componentManager.getProperties() );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index 9ad605e..0372077 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -32,6 +32,7 @@
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.TargetedPID;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.ComponentManager;
 import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
@@ -252,9 +253,13 @@
     }
 
 
-    public Dictionary<String, Object> getProperties()
+    /** 
+     * For ComponentFactoryImpl, this is used only for updating targets on the dependency managers, so we don't need any other 
+     * properties.
+     */
+    public Map<String, Object> getProperties()
     {
-        Dictionary<String, Object> props = getServiceProperties();
+        Map<String, Object> props = new HashMap<String, Object>();
 
         // add target properties of references
         List<ReferenceMetadata> depMetaData = getComponentMetadata().getDependencies();
@@ -332,7 +337,7 @@
 
     //---------- ComponentHolder interface
 
-    public void configurationDeleted( String pid )
+    public void configurationDeleted( TargetedPID pid, TargetedPID factoryPid )
     {
         m_targetedPID = null;
         if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
@@ -451,18 +456,13 @@
     }
 
 
-    public synchronized long getChangeCount( TargetedPID pid)
+    public synchronized long getChangeCount( TargetedPID pid, TargetedPID targetedPid)
     {
         
         return m_changeCount;
     }
 
-    public List<? extends Component> getComponents()
-    {
-        return getComponentList();
-    }
-
-    protected List<AbstractComponentManager<S>> getComponentList()
+	public List<? extends ComponentManager<S>> getComponents()
     {
         List<AbstractComponentManager<S>> cms = new ArrayList<AbstractComponentManager<S>>( );
         cms.add( this );
@@ -557,4 +557,9 @@
     }
 
 
+	public boolean isEnabled() {
+		return isInternalEnabled();
+	}
+
+
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
index b3270c5..82b1778 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
@@ -29,6 +29,7 @@
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.TargetedPID;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.ComponentManager;
 import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Constants;
@@ -117,11 +118,11 @@
 
     //---------- ComponentHolder interface
 
-    public void configurationDeleted( String pid )
+    public void configurationDeleted( TargetedPID pid, TargetedPID factoryPid )
     {
         if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
         {
-            super.configurationDeleted( pid );
+            super.configurationDeleted( pid, factoryPid );
         }
         else
         {
@@ -189,9 +190,9 @@
     }
 
 
-    public List<? extends Component> getComponents()
+    public List<? extends ComponentManager<S>> getComponents()
     {
-        List<AbstractComponentManager<S>> cms = getComponentList();
+        List<AbstractComponentManager<S>> cms = (List<AbstractComponentManager<S>>) super.getComponents();
         getComponentManagers( m_configuredServices, cms );
         return cms;
     }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 061bfec..c359e4a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -39,6 +39,7 @@
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.config.ReferenceManager;
 import org.apache.felix.scr.impl.helper.BindMethod;
 import org.apache.felix.scr.impl.helper.BindMethods;
 import org.apache.felix.scr.impl.helper.Coercions;
@@ -60,7 +61,7 @@
  * declared by a single <code>&lt;reference&gt;</code element in component
  * descriptor.
  */
-public class DependencyManager<S, T> implements Reference
+public class DependencyManager<S, T> implements ReferenceManager<S, T> 
 {
     // mask of states ok to send events
     private static final int STATE_MASK = 
@@ -1303,37 +1304,21 @@
 
     //---------- bound services maintenance -----------------------------------
 
-    /**
-     * Returns an array of <code>ServiceReference</code> instances of all
-     * services this instance is bound to or <code>null</code> if no services
-     * are actually bound.
-     */
-    public ServiceReference<T>[] getServiceReferences()
+    /* (non-Javadoc)
+	 * @see org.apache.felix.scr.impl.manager.ReferenceManager#getServiceReferences()
+	 */
+    public List<ServiceReference<?>> getServiceReferences()
     {
         Collection<RefPair<T>> bound = m_customizer.getRefs(  new AtomicInteger( ) );
-        if ( bound.isEmpty() )
-        {
-            return null;
-        }
-        ServiceReference<T>[] result = new ServiceReference[bound.size()];
-        int i = 0;
+        List<ServiceReference<?>> result = new ArrayList<ServiceReference<?>>(bound.size());
         for (RefPair<T> ref: bound)
         {
-            result[i++] = ref.getRef();
+            result.add(ref.getRef());
         }
         return result;
     }
 
     /**
-     * a mistake, use getServiceReferences instead
-     */
-    @Deprecated
-    public ServiceReference[] getBoundServiceReferences() 
-    {
-        return getServiceReferences();
-    }
-    
-    /**
      * Returns the RefPair containing the given service reference and the bound service
      * or <code>null</code> if this is instance is not currently bound to that
      * service.
@@ -1424,9 +1409,9 @@
 
     //---------- DependencyManager core ---------------------------------------
 
-    /**
-     * Returns the name of the service reference.
-     */
+    /* (non-Javadoc)
+	 * @see org.apache.felix.scr.impl.manager.ReferenceManager#getName()
+	 */
     public String getName()
     {
         return m_dependencyMetadata.getName();
@@ -1785,7 +1770,7 @@
      * apply.</li>
      * </ol>
      */
-    boolean canUpdateDynamically( Dictionary<String, Object> properties )
+    boolean canUpdateDynamically( Map<String, Object> properties )
     {
         // 1. no target filter change
         final String newTarget = ( String ) properties.get( m_dependencyMetadata.getTargetPropertyName() );
@@ -1845,14 +1830,14 @@
      * @param properties The properties containing the optional target service
      *      filter property
      */
-    void setTargetFilter( Dictionary<String, Object> properties )
+    void setTargetFilter( Map<String, Object> properties )
     {
         Integer minimumCardinality = getMinimumCardinality( properties );
         setTargetFilter( ( String ) properties.get( m_dependencyMetadata.getTargetPropertyName() ),
                 minimumCardinality);
     }
 
-    private int getMinimumCardinality(Dictionary<String, Object> properties)
+    private int getMinimumCardinality(Map<String, Object> properties)
     {
         Integer minimumCardinality = null;
         try
@@ -2043,13 +2028,9 @@
     }
 
 
-    /**
-     * Returns the target filter of this dependency as a string or
-     * <code>null</code> if this dependency has no target filter set.
-     *
-     * @return The target filter of this dependency or <code>null</code> if
-     *      none is set.
-     */
+    /* (non-Javadoc)
+	 * @see org.apache.felix.scr.impl.manager.ReferenceManager#getTarget()
+	 */
     public String getTarget()
     {
         return m_target;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
index 1f76587..fadc1e5 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -31,6 +32,8 @@
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.TargetedPID;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.ComponentManager;
+import org.apache.felix.scr.impl.config.ReferenceManager;
 import org.apache.felix.scr.impl.helper.ActivateMethod.ActivatorParameter;
 import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.helper.MethodResult;
@@ -66,10 +69,10 @@
     private Map<String, Object> m_configurationProperties;
     
     // optional properties provided in the ComponentFactory.newInstance method
-    private Dictionary<String, Object> m_factoryProperties;
+    private Map<String, Object> m_factoryProperties;
 
     // the component properties, also used as service properties
-    private Dictionary<String, Object> m_properties;
+    private Map<String, Object> m_properties;
 
     // properties supplied ot ExtComponentContext.updateProperties
     // null if properties are not to be overwritten
@@ -265,7 +268,7 @@
 
         // 4. Bind the target services
 
-        DependencyManager<S, ?> failedDm = null;
+        ReferenceManager<S, ?> failedDm = null;
         for ( DependencyManager<S, ?> dm: getDependencyManagers())
         {
             if ( failedDm == null )
@@ -406,7 +409,7 @@
 
     protected void setFactoryProperties( Dictionary<String, ?> dictionary )
     {
-        m_factoryProperties = copyTo( null, dictionary );
+        m_factoryProperties = copyToMap( dictionary, true );
     }
 
 
@@ -437,9 +440,9 @@
      * Method implements the Component Properties provisioning as described
      * in 112.6, Component Properties.
      *
-     * @return a private Hashtable of component properties
+     * @return a private map of component properties
      */
-    public Dictionary<String, Object> getProperties()
+    public Map<String, Object> getProperties()
     {
 
         if ( m_properties == null )
@@ -447,14 +450,14 @@
 
         	
             // 1. Merge all the config properties
-        	Hashtable<String, Object> props = new Hashtable<String, Object>();
+        	Map<String, Object> props = new HashMap<String, Object>();
         	if ( m_configurationProperties != null ) 
         	{
 				props.putAll(m_configurationProperties);
 			}
 			if ( m_factoryProperties != null)
         	{
-        		copyTo(props, m_factoryProperties);
+        		props.putAll(m_factoryProperties);
         	}
                     
             // 2. set component.name and component.id
@@ -475,7 +478,7 @@
         }
         else
         {
-            m_serviceProperties = copyTo( null, serviceProperties, false );
+            m_serviceProperties = copyToDictionary( serviceProperties, false );
             // set component.name and component.id
             m_serviceProperties.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
             m_serviceProperties.put( ComponentConstants.COMPONENT_ID, getId() );
@@ -679,7 +682,7 @@
 
         // 3. check whether we can dynamically apply the configuration if
         // any target filters influence the bound services
-        final Dictionary<String, Object> props = getProperties();
+        final Map<String, Object> props = getProperties();
         for ( DependencyManager dm: getDependencyManagers() )
         {
             if ( !dm.canUpdateDynamically( props ) )
@@ -867,7 +870,7 @@
     private S getService()
     {
         //should be write locked
-        if (!isEnabled())
+        if (!isInternalEnabled())
         {
             return null;
         }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
index bbace44..8ff781c 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
@@ -23,10 +23,12 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
@@ -102,7 +104,7 @@
     private List<String> m_configurationPid;
 
     // Associated properties (0..*)
-    private Dictionary<String, Object> m_properties = new Hashtable<String, Object>();
+    private Map<String, Object> m_properties = new HashMap<String, Object>();
 
     // List of Property metadata - used while building the meta data
     // while validating the properties contained in the PropertyMetadata
@@ -520,7 +522,11 @@
         {
             throw new IllegalStateException("not yet validated");
         }
-    	return m_configurationPid == null? -1: m_configurationPid.indexOf(pid.getServicePid());
+        if (m_configurationPid == null )
+        {
+        	throw new IllegalStateException( "Apparently trying to configure a component " + m_name + " without a configurationPid using " + pid);
+        }
+    	return m_configurationPid.indexOf(pid.getServicePid());
     }
 
     /**
@@ -695,7 +701,7 @@
      *
      * @return the properties as a Dictionary
      */
-    public Dictionary<String, Object> getProperties()
+    public Map<String, Object> getProperties()
     {
         return m_properties;
     }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
new file mode 100644
index 0000000..163d525
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
@@ -0,0 +1,207 @@
+package org.apache.felix.scr.impl.runtime;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.felix.scr.impl.ComponentRegistry;
+import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.ComponentManager;
+import org.apache.felix.scr.impl.config.ReferenceManager;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.dto.BundleDTO;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.service.component.runtime.dto.BoundReferenceDTO;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
+import org.osgi.service.component.runtime.dto.ReferenceDTO;
+
+public class ServiceComponentRuntimeImpl implements ServiceComponentRuntime {
+	
+	private static final String[] EMPTY = {};
+	
+	private final BundleContext context;
+	private final ComponentRegistry componentRegistry;
+
+
+	public ServiceComponentRuntimeImpl(BundleContext context,
+			ComponentRegistry componentRegistry) {
+		this.context = context;
+		this.componentRegistry = componentRegistry;
+	}
+
+	public Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(
+			Bundle... bundles) {
+		List<ComponentHolder<?>> holders;
+		if (bundles == null || bundles.length == 0)
+		{
+			holders = componentRegistry.getComponentHolders();
+		}
+		else
+		{
+			holders = componentRegistry.getComponentHolders(bundles);
+		}
+
+		List<ComponentDescriptionDTO> result = new ArrayList<ComponentDescriptionDTO>(holders.size());
+		for (ComponentHolder<?> holder: holders)
+		{
+			result.add(holderToDescription(holder));
+		}
+		return result;
+	}
+
+	public ComponentDescriptionDTO getComponentDescriptionDTO(Bundle bundle,
+			String name) {
+		ComponentHolder<?> holder = componentRegistry.getComponentHolder(bundle, name);
+		return holderToDescription(holder);
+	}
+
+	public Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(
+			ComponentDescriptionDTO description) {
+		ComponentHolder<?> holder = getHolderFromDescription( description);
+		//Get a fully filled out valid description DTO
+		description = holderToDescription(holder);
+		List<? extends ComponentManager<?>> managers = holder.getComponents();
+		List<ComponentConfigurationDTO> result = new ArrayList<ComponentConfigurationDTO>(managers.size());
+		for (ComponentManager<?> manager: managers)
+		{
+			result.add(managerToConfiguration(manager, description));
+		}
+		return result;
+	}
+
+	public boolean isComponentEnabled(ComponentDescriptionDTO description) {
+		ComponentHolder<?> holder = getHolderFromDescription( description);
+		return holder.isEnabled();
+	}
+
+	public void enableComponent(ComponentDescriptionDTO description) {
+		ComponentHolder<?> holder = getHolderFromDescription( description);
+		holder.enableComponents(false); //synchronous
+	}
+
+	public void disableComponent(ComponentDescriptionDTO description) {
+		ComponentHolder<?> holder = getHolderFromDescription( description);
+		holder.disableComponents(false); //synchronous
+	}
+	
+	private ComponentConfigurationDTO managerToConfiguration(
+			ComponentManager<?> manager, ComponentDescriptionDTO description) {
+		ComponentConfigurationDTO dto = new ComponentConfigurationDTO();
+		dto.boundReferences = refManagersToDTO(manager.getReferenceManagers());
+		dto.description = description;
+		dto.id = manager.getId();
+		dto.properties = new HashMap<String, Object>(manager.getProperties());//TODO deep copy?
+		dto.state = manager.getState();
+		return dto;
+	}
+
+	private BoundReferenceDTO[] refManagersToDTO(List<? extends ReferenceManager<?, ?>> referenceManagers) {
+		BoundReferenceDTO[] dtos = new BoundReferenceDTO[referenceManagers.size()];
+		for (ReferenceManager<?, ?> ref: referenceManagers)
+		{
+			BoundReferenceDTO dto = new BoundReferenceDTO();
+			dto.name = ref.getName();
+			dto.target = ref.getTarget();
+			List<ServiceReference<?>> serviceRefs = ref.getServiceReferences();
+			ServiceReferenceDTO[] srDTOs = new ServiceReferenceDTO[serviceRefs.size()];
+			int i = 0;
+			for (ServiceReference<?> serviceRef: serviceRefs)
+			{
+				srDTOs[i++] = serviceReferenceToDTO(serviceRef);
+			}
+			dto.serviceReferences = srDTOs;
+		}
+		return dtos;
+	}
+
+	private ServiceReferenceDTO serviceReferenceToDTO(
+			ServiceReference<?> serviceRef) {
+		ServiceReferenceDTO dto = new ServiceReferenceDTO();
+		dto.bundle = serviceRef.getBundle().getBundleId();
+		dto.id = (Long) serviceRef.getProperty("service.id"); //TODO use proper constant
+		//TODO service properties, using bundles
+		return dto;
+	}
+
+	private ComponentHolder getHolderFromDescription(
+			ComponentDescriptionDTO description) {
+		if (description.bundle == null)
+		{
+			throw new IllegalArgumentException("No bundle supplied in ComponentDescriptionDTO named " + description.name);
+		}
+		long bundleId = description.bundle.id;
+		Bundle b = context.getBundle(bundleId);
+		String name = description.name;
+		return componentRegistry.getComponentHolder(b, name);
+	}
+
+	private ComponentDescriptionDTO holderToDescription( ComponentHolder<?> holder )
+	{
+		ComponentDescriptionDTO dto = new ComponentDescriptionDTO();
+		ComponentMetadata m = holder.getComponentMetadata();
+		dto.activate = m.getActivate();
+		dto.bundle = bundleToDTO(holder.getActivator().getBundleContext());
+		dto.configurationPid = m.getConfigurationPid().toArray(new String[m.getConfigurationPid().size()]);
+		dto.configurationPolicy = m.getConfigurationPolicy();
+		dto.deactivate = m.getDeactivate();
+		dto.defaultEnabled = m.isEnabled();
+		dto.factory = m.getFactoryIdentifier();
+		dto.immediate = m.isImmediate();
+		dto.implementationClass = m.getImplementationClassName();
+		dto.modified = m.getModified();
+		dto.name = m.getName();
+		dto.properties = new HashMap<String, Object>(m.getProperties());// TODO deep copy of arrays
+		dto.references = refsToDTO(m.getDependencies());
+		dto.scope = m.getServiceMetadata() == null? null: m.getServiceMetadata().getScope().name();
+		dto.serviceInterfaces = m.getServiceMetadata() == null? EMPTY: m.getServiceMetadata().getProvides();
+		return dto;
+	}
+
+	private ReferenceDTO[] refsToDTO(List<ReferenceMetadata> dependencies) {
+		ReferenceDTO[] dtos = new ReferenceDTO[dependencies.size()];
+		int i = 0;
+		for (ReferenceMetadata r: dependencies)
+		{
+			ReferenceDTO dto = new ReferenceDTO();
+			dto.bind = r.getBind();
+			dto.cardinality = r.getCardinality();
+			dto.interfaceName = r.getInterface();
+			dto.name = r.getName();
+			dto.policy = r.getPolicy();
+			dto.policyOption = r.getPolicyOption();
+			dto.scope = r.getScope().name();
+			dto.target = r.getTarget();
+			dto.unbind = r.getUnbind();
+			dto.updated = r.getUpdated();
+			dtos[i] = dto;
+		}
+		return dtos;
+	}
+
+	private BundleDTO bundleToDTO(BundleContext bundleContext) {
+		if (bundleContext == null)
+		{
+			return null;
+		}
+		Bundle bundle = bundleContext.getBundle();
+		if (bundle == null)
+		{
+			return null;
+		}
+		BundleDTO b = new BundleDTO();
+		b.id = bundle.getBundleId();
+		b.lastModified = bundle.getLastModified();
+		b.state = bundle.getState();
+		b.symbolicName = bundle.getSymbolicName();
+		b.version = bundle.getVersion().toString();
+		return b;
+	}
+
+}
diff --git a/scr/src/main/java/org/osgi/dto/DTO.java b/scr/src/main/java/org/osgi/dto/DTO.java
new file mode 100644
index 0000000..acb9dd3
--- /dev/null
+++ b/scr/src/main/java/org/osgi/dto/DTO.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * 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.osgi.dto;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Super type for Data Transfer Objects.
+ * 
+ * All data transfer objects are easily serializable having only public fields
+ * of primitive types and their wrapper classes, Strings, and DTOs. List, Set,
+ * Map and array aggregates may also be used. The aggregates must only hold
+ * objects of the listed types or aggregates.
+ * 
+ * @author $Id: 36dd2d0b9df1b8a6f67c74eeaad1cc9e20e19574 $
+ * @NotThreadSafe
+ */
+public abstract class DTO {
+
+    /**
+     * Return a string representation of this DTO suitable for use when
+     * debugging.
+     * 
+     * <p>
+     * The format of the string representation is not specified and subject to
+     * change.
+     * 
+     * @return A string representation of this DTO suitable for use when
+     *         debugging.
+     */
+    @Override
+    public String toString() {
+        return appendValue(new StringBuilder(), new IdentityHashMap<Object, String>(), "#", this).toString();
+    }
+
+    /**
+     * Append the specified DTO's string representation to the specified
+     * StringBuilder.
+     * 
+     * <p>
+     * This method handles circular DTO references.
+     * 
+     * @param result StringBuilder to which the string representation is
+     *        appended.
+     * @param objectRefs References to "seen" objects.
+     * @param refpath The reference path of the specified DTO.
+     * @param dto The DTO whose string representation is to be appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendDTO(final StringBuilder result, final Map<Object, String> objectRefs, final String refpath, final DTO dto) {
+        result.append("{");
+        String delim = "";
+        for (Field field : dto.getClass().getFields()) {
+            if (Modifier.isStatic(field.getModifiers())) {
+                continue;
+            }
+            result.append(delim);
+            final String name = field.getName();
+            appendString(result, name);
+            result.append(":");
+            Object value = null;
+            try {
+                value = field.get(dto);
+            } catch (IllegalAccessException e) {
+                // use null value;
+            }
+            appendValue(result, objectRefs, refpath + "/" + name, value);
+            delim = ", ";
+        }
+        result.append("}");
+        return result;
+    }
+
+    /**
+     * Append the specified value's string representation to the specified
+     * StringBuilder.
+     * 
+     * @param result StringBuilder to which the string representation is
+     *        appended.
+     * @param objectRefs References to "seen" objects.
+     * @param refpath The reference path of the specified value.
+     * @param value The object whose string representation is to be appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendValue(final StringBuilder result, final Map<Object, String> objectRefs, final String refpath, final Object value) {
+        if (value == null) {
+            return result.append("null");
+        }
+        // Simple Java types
+        if (value instanceof String || value instanceof Character) {
+            return appendString(result, compress(value.toString()));
+        }
+        if (value instanceof Number || value instanceof Boolean) {
+            return result.append(value.toString());
+        }
+
+        // Complex types
+        final String path = objectRefs.get(value);
+        if (path != null) {
+            result.append("{\"$ref\":");
+            appendString(result, path);
+            result.append("}");
+            return result;
+        }
+        objectRefs.put(value, refpath);
+
+        if (value instanceof DTO) {
+            return appendDTO(result, objectRefs, refpath, (DTO) value);
+        }
+        if (value instanceof Map) {
+            return appendMap(result, objectRefs, refpath, (Map<?, ?>) value);
+        }
+        if (value instanceof List || value instanceof Set) {
+            return appendIterable(result, objectRefs, refpath, (Iterable<?>) value);
+        }
+        if (value.getClass().isArray()) {
+            return appendArray(result, objectRefs, refpath, value);
+        }
+        return appendString(result, compress(value.toString()));
+    }
+
+    /**
+     * Append the specified array's string representation to the specified
+     * StringBuilder.
+     * 
+     * @param result StringBuilder to which the string representation is
+     *        appended.
+     * @param objectRefs References to "seen" objects.
+     * @param refpath The reference path of the specified array.
+     * @param array The array whose string representation is to be appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendArray(final StringBuilder result, final Map<Object, String> objectRefs, final String refpath, final Object array) {
+        result.append("[");
+        final int length = Array.getLength(array);
+        for (int i = 0; i < length; i++) {
+            if (i > 0) {
+                result.append(",");
+            }
+            appendValue(result, objectRefs, refpath + "/" + i, Array.get(array, i));
+        }
+        result.append("]");
+        return result;
+    }
+
+    /**
+     * Append the specified iterable's string representation to the specified
+     * StringBuilder.
+     * 
+     * @param result StringBuilder to which the string representation is
+     *        appended.
+     * @param objectRefs References to "seen" objects.
+     * @param refpath The reference path of the specified list.
+     * @param iterable The iterable whose string representation is to be
+     *        appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendIterable(final StringBuilder result, final Map<Object, String> objectRefs, final String refpath, final Iterable<?> iterable) {
+        result.append("[");
+        int i = 0;
+        for (Object item : iterable) {
+            if (i > 0) {
+                result.append(",");
+            }
+            appendValue(result, objectRefs, refpath + "/" + i, item);
+            i++;
+        }
+        result.append("]");
+        return result;
+    }
+
+    /**
+     * Append the specified map's string representation to the specified
+     * StringBuilder.
+     * 
+     * @param result StringBuilder to which the string representation is
+     *        appended.
+     * @param objectRefs References to "seen" objects.
+     * @param refpath The reference path of the specified map.
+     * @param map The map whose string representation is to be appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendMap(final StringBuilder result, final Map<Object, String> objectRefs, final String refpath, final Map<?, ?> map) {
+        result.append("{");
+        String delim = "";
+        for (Map.Entry<?, ?> entry : map.entrySet()) {
+            result.append(delim);
+            final String name = String.valueOf(entry.getKey());
+            appendString(result, name);
+            result.append(":");
+            final Object value = entry.getValue();
+            appendValue(result, objectRefs, refpath + "/" + name, value);
+            delim = ", ";
+        }
+        result.append("}");
+        return result;
+    }
+
+    /**
+     * Append the specified string to the specified StringBuilder.
+     * 
+     * @param result StringBuilder to which the string is appended.
+     * @param string The string to be appended.
+     * @return The specified StringBuilder.
+     */
+    private static StringBuilder appendString(final StringBuilder result, final CharSequence string) {
+        result.append("\"");
+        int i = result.length();
+        result.append(string);
+        while (i < result.length()) { // escape if necessary
+            char c = result.charAt(i);
+            if ((c == '"') || (c == '\\')) {
+                result.insert(i, '\\');
+                i = i + 2;
+                continue;
+            }
+            if (c < 0x20) {
+                result.insert(i + 1, Integer.toHexString(c | 0x10000));
+                result.replace(i, i + 2, "\\u");
+                i = i + 6;
+                continue;
+            }
+            i++;
+        }
+        result.append("\"");
+        return result;
+    }
+
+    /**
+     * Compress, in length, the specified string.
+     * 
+     * @param in The string to potentially compress.
+     * @return The string compressed, if necessary.
+     */
+    private static CharSequence compress(final CharSequence in) {
+        final int length = in.length();
+        if (length <= 21) {
+            return in;
+        }
+        StringBuilder result = new StringBuilder(21);
+        result.append(in, 0, 9);
+        result.append("...");
+        result.append(in, length - 9, length);
+        return result;
+    }
+}
diff --git a/scr/src/main/java/org/osgi/dto/package-info.java b/scr/src/main/java/org/osgi/dto/package-info.java
new file mode 100644
index 0000000..c3010b3
--- /dev/null
+++ b/scr/src/main/java/org/osgi/dto/package-info.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2012, 2013). All Rights Reserved.
+ *
+ * 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.
+ */
+
+/**
+ * OSGi Data Transfer Object Package Version 1.0.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.dto; version="[1.0,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.dto; version="[1.0,1.1)"}
+ *
+ * @author $Id: 1209bb5e60e6b6fc8239119a2dd4a2c15b9a40f2 $
+ */
+
+//@Version("1.0")
+package org.osgi.dto;
+
+//import org.osgi.annotation.versioning.Version;
+
diff --git a/scr/src/main/java/org/osgi/dto/packageinfo b/scr/src/main/java/org/osgi/dto/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/scr/src/main/java/org/osgi/dto/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/scr/src/main/java/org/osgi/framework/dto/BundleDTO.java b/scr/src/main/java/org/osgi/framework/dto/BundleDTO.java
new file mode 100644
index 0000000..6b83401
--- /dev/null
+++ b/scr/src/main/java/org/osgi/framework/dto/BundleDTO.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ *
+ * 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.osgi.framework.dto;
+
+import org.osgi.dto.DTO;
+import org.osgi.framework.Bundle;
+
+/**
+ * Data Transfer Object for a Bundle.
+ * 
+ * <p>
+ * A Bundle can be adapted to provide a {@code BundleDTO} for the Bundle.
+ * 
+ * @author $Id: aa30709351d8fe70b19c9ea99456ebd15ecab7c3 $
+ * @NotThreadSafe
+ */
+public class BundleDTO extends DTO {
+    /**
+	 * The bundle's unique identifier.
+	 * 
+	 * @see Bundle#getBundleId()
+	 */
+    public long   id;
+
+    /**
+	 * The time when the bundle was last modified.
+	 * 
+	 * @see Bundle#getLastModified()
+	 */
+    public long   lastModified;
+
+    /**
+	 * The bundle's state.
+	 * 
+	 * @see Bundle#getState()
+	 */
+    public int    state;
+
+    /**
+	 * The bundle's symbolic name.
+	 * 
+	 * @see Bundle#getSymbolicName()
+	 */
+    public String symbolicName;
+
+    /**
+	 * The bundle's version.
+	 * 
+	 * @see Bundle#getVersion()
+	 */
+    public String version;
+}
diff --git a/scr/src/main/java/org/osgi/framework/dto/FrameworkDTO.java b/scr/src/main/java/org/osgi/framework/dto/FrameworkDTO.java
new file mode 100644
index 0000000..7b32f93
--- /dev/null
+++ b/scr/src/main/java/org/osgi/framework/dto/FrameworkDTO.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ *
+ * 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.osgi.framework.dto;
+
+import java.util.List;
+import java.util.Map;
+import org.osgi.dto.DTO;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Data Transfer Object for a Framework.
+ * 
+ * <p>
+ * The System Bundle can be adapted to provide a {@code FrameworkDTO} for the
+ * framework of the system bundle. A {@code FrameworkDTO} obtained from a
+ * framework will contain only the launch properties of the framework. These
+ * properties will not include the System properties.
+ * 
+ * @author $Id: 7c525727cbe877e888b460cd14d8f9054f99ee0c $
+ * @NotThreadSafe
+ */
+public class FrameworkDTO extends DTO {
+    /**
+	 * The bundles that are installed in the framework.
+	 * 
+	 * @see BundleContext#getBundles()
+	 */
+    public List<BundleDTO>           bundles;
+
+    /**
+	 * The launch properties of the framework.
+	 * 
+	 * The value type must be a numerical type, Boolean, String, DTO or an array
+	 * of any of the former.
+	 * 
+	 * @see BundleContext#getProperty(String)
+	 */
+    public Map<String, Object>       properties;
+
+    /**
+	 * The services that are registered in the framework.
+	 * 
+	 * @see BundleContext#getServiceReferences(String, String)
+	 */
+    public List<ServiceReferenceDTO> services;
+}
diff --git a/scr/src/main/java/org/osgi/framework/dto/ServiceReferenceDTO.java b/scr/src/main/java/org/osgi/framework/dto/ServiceReferenceDTO.java
new file mode 100644
index 0000000..d08e2e3
--- /dev/null
+++ b/scr/src/main/java/org/osgi/framework/dto/ServiceReferenceDTO.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ *
+ * 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.osgi.framework.dto;
+
+import java.util.Map;
+import org.osgi.dto.DTO;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Data Transfer Object for a ServiceReference.
+ * 
+ * <p>
+ * {@code ServiceReferenceDTO}s for all registered services can be obtained from
+ * a {@link FrameworkDTO}. An installed Bundle can be adapted to provide a
+ * {@code ServiceReferenceDTO[]} of the services registered by the Bundle. A
+ * {@code ServiceReferenceDTO} obtained from a framework must convert service
+ * property values which are not valid value types for DTOs to type
+ * {@code String} using {@code String.valueOf(Object)}.
+ * 
+ * @author $Id: 2c70b84f28c41fb51c488cb03950a46188ea209f $
+ * @NotThreadSafe
+ */
+public class ServiceReferenceDTO extends DTO {
+    /**
+	 * The id of the service.
+	 * 
+	 * @see Constants#SERVICE_ID
+	 */
+    public long                id;
+
+    /**
+	 * The id of the bundle that registered the service.
+	 * 
+	 * @see ServiceReference#getBundle()
+	 */
+    public long                bundle;
+
+    /**
+	 * The properties for the service.
+	 * 
+	 * The value type must be a numerical type, Boolean, String, DTO or an array
+	 * of any of the former.
+	 * 
+	 * @see ServiceReference#getProperty(String)
+	 */
+    public Map<String, Object> properties;
+
+    /**
+	 * The ids of the bundles that are using the service.
+	 * 
+	 * @see ServiceReference#getUsingBundles()
+	 */
+    public long[]              usingBundles;
+}
diff --git a/scr/src/main/java/org/osgi/framework/dto/package-info.java b/scr/src/main/java/org/osgi/framework/dto/package-info.java
new file mode 100644
index 0000000..5c0bffc
--- /dev/null
+++ b/scr/src/main/java/org/osgi/framework/dto/package-info.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2012, 2014). All Rights Reserved.
+ * 
+ * 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.
+ */
+
+/**
+ * OSGi Data Transfer Object Framework Package Version 1.8.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.dto; version="[1.8,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.framework.dto; version="[1.8,1.9)"}
+ * 
+ * @author $Id: 2acfb6f1633e18f1ceedd27c04e70131cae4f293 $
+ */
+
+//@Version("1.8")
+package org.osgi.framework.dto;
+
+//import org.osgi.annotation.versioning.Version;
+
diff --git a/scr/src/main/java/org/osgi/framework/dto/packageinfo b/scr/src/main/java/org/osgi/framework/dto/packageinfo
new file mode 100644
index 0000000..ed9885d
--- /dev/null
+++ b/scr/src/main/java/org/osgi/framework/dto/packageinfo
@@ -0,0 +1 @@
+version 1.8
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/ServiceComponentRuntime.java b/scr/src/main/java/org/osgi/service/component/runtime/ServiceComponentRuntime.java
new file mode 100755
index 0000000..45db87df
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/ServiceComponentRuntime.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) OSGi Alliance (2013, 2014). All Rights Reserved.
+ *
+ * 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.osgi.service.component.runtime;
+
+import java.util.Collection;
+//import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.Bundle;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
+
+/**
+ * The {@code ServiceComponentRuntime} service represents the Declarative
+ * Services main controller also known as the Service Component Runtime or SCR
+ * for short. It provides access to the components managed by the Service
+ * Component Runtime.
+ * 
+ * <p>
+ * This service differentiates between a {@link ComponentDescriptionDTO} and a
+ * {@link ComponentConfigurationDTO}. A {@link ComponentDescriptionDTO} is a
+ * representation of a declared component description. A
+ * {@link ComponentConfigurationDTO} is a representation of an actual instance of a
+ * declared component description parameterized by component properties.
+ * <p>
+ * 
+ * Access to this service requires the
+ * {@code ServicePermission[ServiceComponentRuntime, GET]} permission. It is
+ * intended that only administrative bundles should be granted this permission
+ * to limit access to the potentially intrusive methods provided by this
+ * service.
+ * 
+ * @ThreadSafe
+ * @since 1.3
+ * @author $Id: 0b736eb18ed9ae337ef04765d1c006049a246c56 $
+ */
+//@ProviderType
+public interface ServiceComponentRuntime {
+
+	/**
+	 * Returns the component descriptions declared by the specified active
+	 * bundles.
+	 * 
+	 * <p>
+	 * Only component descriptions from active bundles are returned. If the
+	 * specified bundles have no declared components or are not active, an empty
+	 * collection is returned.
+	 * 
+	 * @param bundles The bundles whose declared component descriptions are to
+	 *        be returned. Specifying no bundles, or the equivalent of an empty
+	 *        {@code Bundle} array, will return the declared component
+	 *        descriptions from all active bundles.
+	 * @return The declared component descriptions of the specified active
+	 *         {@code bundles}. An empty collection is returned if there are no
+	 *         component descriptions for the specified active bundles.
+	 */
+	Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(Bundle... bundles);
+
+	/**
+	 * Returns the {@link ComponentDescriptionDTO} declared with the specified name
+	 * by the specified bundle.
+	 * 
+	 * <p>
+	 * Only component descriptions from active bundles are returned.
+	 * {@code null} if no such component is declared by the given {@code bundle}
+	 * or the bundle is not active.
+	 * 
+	 * @param bundle The bundle declaring the component description. Must not be
+	 *        {@code null}.
+	 * @param name The name of the component description. Must not be
+	 *        {@code null}.
+	 * @return The declared component description or {@code null} if the
+	 *         specified bundle is not active or does not declare a component
+	 *         description with the specified name.
+	 */
+	ComponentDescriptionDTO getComponentDescriptionDTO(Bundle bundle, String name);
+
+	/**
+	 * Returns the component configurations for the specified component
+	 * description.
+	 * 
+	 * @param description The component description. Must not be {@code null}.
+	 * @return A collection containing a snapshot of the current component
+	 *         configurations for the specified component description. An empty
+	 *         collection is returned if there are none.
+	 */
+	Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(ComponentDescriptionDTO description);
+
+	/**
+	 * Returns whether the specified component description is currently enabled.
+	 * 
+	 * <p>
+	 * The enabled state of a component description is initially set by the
+	 * {@link ComponentDescriptionDTO#defaultEnabled enabled} attribute of the
+	 * component description.
+	 * 
+	 * @param description The component description. Must not be {@code null}.
+	 * @return {@code true} if the specified component description is currently
+	 *         enabled. Otherwise, {@code false}.
+	 * @see #enableComponent(ComponentDescriptionDTO)
+	 * @see #disableComponent(ComponentDescriptionDTO)
+	 * @see ComponentContext#disableComponent(String)
+	 * @see ComponentContext#enableComponent(String)
+	 */
+	boolean isComponentEnabled(ComponentDescriptionDTO description);
+
+	/**
+	 * Enables the specified component description.
+	 * 
+	 * <p>
+	 * If the specified component description is currently enabled, this method
+	 * has no effect.
+	 * 
+	 * @param description The component description to enable. Must not be
+	 *        {@code null}.
+	 * @see #isComponentEnabled(ComponentDescriptionDTO)
+	 */
+	void enableComponent(ComponentDescriptionDTO description);
+
+	/**
+	 * Disables the specified component description.
+	 * 
+	 * <p>
+	 * If the specified component description is currently disabled, this method
+	 * has no effect.
+	 * 
+	 * @param description The component description to disable. Must not be
+	 *        {@code null}.
+	 * @see #isComponentEnabled(ComponentDescriptionDTO)
+	 */
+	void disableComponent(ComponentDescriptionDTO description);
+}
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/BoundReferenceDTO.java b/scr/src/main/java/org/osgi/service/component/runtime/dto/BoundReferenceDTO.java
new file mode 100755
index 0000000..b843280
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/BoundReferenceDTO.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2013, 2014). All Rights Reserved.
+ *
+ * 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.osgi.service.component.runtime.dto;
+
+import org.osgi.dto.DTO;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+
+/**
+ * A representation of a bound reference to a service.
+ * 
+ * @since 1.3
+ * @NotThreadSafe
+ * @author $Id: 1ba28863312f0c0784e4a5596f991a6a6a68c147 $
+ */
+public class BoundReferenceDTO extends DTO {
+	/**
+	 * The name of the declared reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code name} attribute of the {@code reference}
+	 * element of the component description.
+	 * 
+	 * @see ComponentDescriptionDTO#name
+	 */
+	public String					name;
+
+	/**
+	 * The target property of the bound reference.
+	 * 
+	 * <p>
+	 * This is the value of the {@link ComponentConfigurationDTO#properties
+	 * component property} whose name is the concatenation of the
+	 * {@link ReferenceDTO#name declared reference name} and
+	 * &quot;.target&quot;. This will be {@code null} if no target property is
+	 * set for the reference.
+	 */
+	public String					target;
+
+	/**
+	 * The bound services.
+	 * 
+	 * <p>
+	 * Each {@link ServiceReferenceDTO} in the array represents a service bound
+	 * to the component configuration.
+	 */
+	public ServiceReferenceDTO[]	serviceReferences;
+}
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentConfigurationDTO.java b/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentConfigurationDTO.java
new file mode 100755
index 0000000..fbed36d
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentConfigurationDTO.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) OSGi Alliance (2013, 2014). All Rights Reserved.
+ *
+ * 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.osgi.service.component.runtime.dto;
+
+import java.util.Map;
+import org.osgi.dto.DTO;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * A representation of an actual instance of a declared component description
+ * parameterized by component properties.
+ * 
+ * @since 1.3
+ * @NotThreadSafe
+ * @author $Id: b3f49d694f497e55dc7ffed0e7d910fb3bab83da $
+ */
+public class ComponentConfigurationDTO extends DTO {
+	/**
+	 * The component configuration is unsatisfied.
+	 * 
+	 * <p>
+	 * This is the initial state of a component configuration. When the
+	 * component configuration becomes satisfied it enters the
+	 * {@link #SATISFIED} state.
+	 */
+	public static final int		UNSATISFIED		= 1;
+
+	/**
+	 * The component configuration is satisfied.
+	 * 
+	 * <p>
+	 * Any {@link ComponentDescriptionDTO#serviceInterfaces services} declared by
+	 * the component description are registered.
+	 * 
+	 * If the component configuration becomes unsatisfied for any reason, any
+	 * declared services must be unregistered and the component configuration
+	 * returns to the {@link #UNSATISFIED} state.
+	 */
+	public static final int		SATISFIED		= 2;
+
+	/**
+	 * The component configuration is active.
+	 * 
+	 * <p>
+	 * This is the normal operational state of a component configuration. The
+	 * component configuration will move to the {@link #SATISFIED} state when it
+	 * is deactivated.
+	 */
+	public static final int			ACTIVE		= 4;
+
+	/**
+	 * The representation of the component configuration's component
+	 * description.
+	 */
+	public ComponentDescriptionDTO	description;
+
+	/**
+	 * The current state of the component configuration.
+	 * 
+	 * <p>
+	 * This is one of {@link #UNSATISFIED}, {@link #SATISFIED} or
+	 * {@link #ACTIVE}.
+	 */
+	public int					state;
+
+	/**
+	 * The component properties for the component configuration.
+	 * 
+	 * @see ComponentContext#getProperties()
+	 */
+	public Map<String, Object>	properties;
+
+	/**
+	 * The currently bound references.
+	 * 
+	 * <p>
+	 * Each {@link BoundReferenceDTO} in the array represents a service bound to a
+	 * reference of the component configuration. The array will be empty if the
+	 * component configuration has no bound references.
+	 */
+	public BoundReferenceDTO[]		boundReferences;
+	
+	/**
+	 * The id of the component description.
+	 * 
+	 * <p>
+	 * The id is a non-persistent, unique value assigned at runtime. The id is
+	 * also available as the {@code component.id} component property.
+	 */
+	public long					id;
+}
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentDescriptionDTO.java b/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentDescriptionDTO.java
new file mode 100755
index 0000000..986d463
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/ComponentDescriptionDTO.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) OSGi Alliance (2013, 2014). All Rights Reserved.
+ *
+ * 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.osgi.service.component.runtime.dto;
+
+import java.util.Map;
+import org.osgi.dto.DTO;
+import org.osgi.framework.dto.BundleDTO;
+
+/**
+ * A representation of a declared component description.
+ * 
+ * @since 1.3
+ * @NotThreadSafe
+ * @author $Id: f0bf3f3036179db049645595e631489455affe8a $
+ */
+public class ComponentDescriptionDTO extends DTO {
+	/**
+	 * The name of the component.
+	 * 
+	 * <p>
+	 * This is declared in the {@code name} attribute of the {@code component}
+	 * element. This will be the default name if the component description does
+	 * not declare a name.
+	 */
+	public String				name;
+
+	/**
+	 * The bundle declaring the component description.
+	 */
+	public BundleDTO			bundle;
+
+	/**
+	 * The component factory name.
+	 * 
+	 * <p>
+	 * This is declared in the {@code factory} attribute of the
+	 * {@code component} element. This will be {@code null} if the component
+	 * description is not declared as a component factory.
+	 */
+	public String				factory;
+
+	/**
+	 * The service scope.
+	 * 
+	 * <p>
+	 * This is declared in the {@code scope} attribute of the {@code service}
+	 * element.
+	 */
+	public String				scope;
+
+	/**
+	 * The fully qualified name of the implementation class.
+	 * 
+	 * <p>
+	 * This is declared in the {@code class} attribute of the
+	 * {@code implementation} element.
+	 */
+	public String				implementationClass;
+
+	/**
+	 * The initial enabled state.
+	 * 
+	 * <p>
+	 * This is declared in the {@code enabled} attribute of the
+	 * {@code component} element.
+	 */
+	public boolean				defaultEnabled;
+
+	/**
+	 * The immediate state.
+	 * 
+	 * <p>
+	 * This is declared in the {@code immediate} attribute of the
+	 * {@code component} element.
+	 */
+	public boolean				immediate;
+
+	/**
+	 * The fully qualified names of the service interfaces.
+	 * 
+	 * <p>
+	 * These are declared in the {@code interface} attribute of the
+	 * {@code provide} elements. The array will be empty if the component
+	 * description does not declare any service interfaces.
+	 */
+	public String[]				serviceInterfaces;
+
+	/**
+	 * The declared component properties.
+	 * 
+	 * <p>
+	 * These are declared in the {@code property} and {@code properties}
+	 * elements.
+	 */
+	public Map<String, Object>	properties;
+
+	/**
+	 * The referenced services.
+	 * 
+	 * <p>
+	 * These are declared in the {@code reference} elements. The array will be
+	 * empty if the component description does not declare references to any
+	 * services.
+	 */
+	public ReferenceDTO[]			references;
+
+	/**
+	 * The name of the activate method.
+	 * 
+	 * <p>
+	 * This is declared in the {@code activate} attribute of the
+	 * {@code component} element. This will be {@code null} if the component
+	 * description does not declare an activate method name.
+	 */
+	public String				activate;
+
+	/**
+	 * The name of the deactivate method.
+	 * 
+	 * <p>
+	 * This is declared in the {@code deactivate} attribute of the
+	 * {@code component} element. This will be {@code null} if the component
+	 * description does not declare a deactivate method name.
+	 */
+	public String				deactivate;
+
+	/**
+	 * The name of the modified method.
+	 * 
+	 * <p>
+	 * This is declared in the {@code modified} attribute of the
+	 * {@code component} element. This will be {@code null} if the component
+	 * description does not declare a modified method name.
+	 */
+	public String				modified;
+
+	/**
+	 * The configuration policy.
+	 * 
+	 * <p>
+	 * This is declared in the {@code configuration-policy} attribute of the
+	 * {@code component} element. This will be the default configuration policy
+	 * if the component description does not declare a configuration policy.
+	 */
+	public String				configurationPolicy;
+
+	/**
+	 * The configuration pid.
+	 * 
+	 * <p>
+	 * This is declared in the {@code configuration-pid} attribute of the
+	 * {@code component} element. This will be the default configuration pid if
+	 * the component description does not declare a configuration pid.
+	 */
+	public String[]				configurationPid;
+
+}
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/ReferenceDTO.java b/scr/src/main/java/org/osgi/service/component/runtime/dto/ReferenceDTO.java
new file mode 100755
index 0000000..33fec8b
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/ReferenceDTO.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) OSGi Alliance (2013, 2014). All Rights Reserved.
+ *
+ * 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.osgi.service.component.runtime.dto;
+
+import org.osgi.dto.DTO;
+
+/**
+ * A representation of a declared reference to a service.
+ * 
+ * @since 1.3
+ * @NotThreadSafe
+ * @author $Id: 2fc8a3deac2ece6b9fff4878dbe3f082faadd5f8 $
+ */
+public class ReferenceDTO extends DTO {
+	/**
+	 * The name of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code name} attribute of the {@code reference}
+	 * element. This will be the default name if the component description does
+	 * not declare a name for the reference.
+	 */
+	public String	name;
+
+	/**
+	 * The service interface of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code interface} attribute of the
+	 * {@code reference} element.
+	 */
+	public String	interfaceName;
+
+	/**
+	 * The cardinality of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code cardinality} attribute of the
+	 * {@code reference} element. This will be the default cardinality if the
+	 * component description does not declare a cardinality for the reference.
+	 */
+	public String	cardinality;
+
+	/**
+	 * The policy of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code policy} attribute of the {@code reference}
+	 * element. This will be the default policy if the component description
+	 * does not declare a policy for the reference.
+	 */
+	public String	policy;
+
+	/**
+	 * The policy option of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code policy-option} attribute of the
+	 * {@code reference} element. This will be the default policy option if the
+	 * component description does not declare a policy option for the reference.
+	 */
+	public String	policyOption;
+
+	/**
+	 * The target of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code target} attribute of the {@code reference}
+	 * element. This will be {@code null} if the component description does not
+	 * declare a target for the reference.
+	 */
+	public String	target;
+
+	/**
+	 * The name of the bind method of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code bind} attribute of the {@code reference}
+	 * element. This will be {@code null} if the component description does not
+	 * declare a bind method for the reference.
+	 */
+	public String	bind;
+
+	/**
+	 * The name of the unbind method of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code unbind} attribute of the {@code reference}
+	 * element. This will be {@code null} if the component description does not
+	 * declare an unbind method for the reference.
+	 */
+	public String	unbind;
+
+	/**
+	 * The name of the updated method of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code updated} attribute of the
+	 * {@code reference} element. This will be {@code null} if the component
+	 * description does not declare an updated method for the reference.
+	 */
+	public String	updated;
+
+	/**
+	 * The scope of the reference.
+	 * 
+	 * <p>
+	 * This is declared in the {@code scope} attribute of the {@code reference}
+	 * element. This will be the default scope if the component description does
+	 * not declare a scope for the reference.
+	 */
+	public String	scope;
+}
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/package-info.java b/scr/src/main/java/org/osgi/service/component/runtime/dto/package-info.java
new file mode 100644
index 0000000..bc806dd
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/package-info.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
+ *
+ * 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.
+ */
+
+/**
+ * Service Component Runtime Data Transfer Objects Package Version 1.3.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.component.runtime.dto; version="[1.3,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.component.runtime.dto; version="[1.3,1.4)"}
+ *
+ * @author $Id: d7d82da09d67a3ce4274ad8554966c1952a2b4de $
+ */
+
+//@Version("1.3")
+package org.osgi.service.component.runtime.dto;
+
+//import org.osgi.annotation.versioning.Version;
+
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/dto/packageinfo b/scr/src/main/java/org/osgi/service/component/runtime/dto/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/dto/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/package-info.java b/scr/src/main/java/org/osgi/service/component/runtime/package-info.java
new file mode 100644
index 0000000..55a20c1
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/package-info.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) OSGi Alliance (2013). All Rights Reserved.
+ *
+ * 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.
+ */
+
+/**
+ * Service Component Runtime Package Version 1.3.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.component.runtime; version="[1.3,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.component.runtime; version="[1.3,1.4)"}
+ *
+ * @author $Id: 3d4fa42ce33a4682cbaeee3f094b558e6ea6080f $
+ */
+
+//@Version("1.3")
+package org.osgi.service.component.runtime;
+
+//import org.osgi.annotation.versioning.Version;
+
diff --git a/scr/src/main/java/org/osgi/service/component/runtime/packageinfo b/scr/src/main/java/org/osgi/service/component/runtime/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/scr/src/main/java/org/osgi/service/component/runtime/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/manager/AbstractComponentManagerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/manager/AbstractComponentManagerTest.java
index 5d34b99..3733c22 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/manager/AbstractComponentManagerTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/manager/AbstractComponentManagerTest.java
@@ -19,6 +19,8 @@
 package org.apache.felix.scr.impl.manager;
 
 import java.util.Hashtable;
+import java.util.Map;
+
 import junit.framework.TestCase;
 
 public class AbstractComponentManagerTest extends TestCase
@@ -30,7 +32,7 @@
         ht.put( "p1", "v1" );
         ht.put( "p.2", "v2" );
         ht.put( ".p3", "v3" );
-        final Hashtable dict = (Hashtable) AbstractComponentManager.copyTo( null, ht, true );
+        final Map dict = AbstractComponentManager.copyToMap( ht, true );
         assertNotNull( "Copy result is not null", dict );
         assertEquals( "Number of items", 3, dict.size() );
         assertEquals( "Value for key p1", "v1", dict.get( "p1" ) );
@@ -44,7 +46,7 @@
         ht.put( "p1", "v1" );
         ht.put( "p.2", "v2" );
         ht.put( ".p3", "v3" );
-        final Hashtable dict = (Hashtable) AbstractComponentManager.copyTo( null, ht, false );
+        final Map dict = AbstractComponentManager.copyToMap( ht, false );
         assertNotNull( "Copy result is not null", dict );
         assertEquals( "Number of items", 2, dict.size() );
         assertEquals( "Value for key p1", "v1", dict.get( "p1" ) );