diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
new file mode 100644
index 0000000..fe1416c
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/Activator.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.compat;
+
+
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.ScrInfo;
+import org.apache.felix.scr.ScrService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+
+public class Activator
+{
+    // tracker of the runtime service
+    private volatile ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime> runtimeTracker;
+
+    // the service registrations
+    private final Map<Long, ServiceRegistration<ScrService>> scrServiceRegMap = new ConcurrentHashMap<Long, ServiceRegistration<ScrService>>();
+
+    // the service registrations
+    private final Map<Long, ServiceRegistration<ScrInfo>> scrCommandRegMap = new ConcurrentHashMap<Long, ServiceRegistration<ScrInfo>>();
+
+    public void start( final BundleContext context ) throws Exception
+    {
+        this.runtimeTracker = new ServiceTracker<ServiceComponentRuntime, ServiceComponentRuntime>(context, ServiceComponentRuntime.class,
+                new ServiceTrackerCustomizer<ServiceComponentRuntime, ServiceComponentRuntime>()
+                {
+
+                    public ServiceComponentRuntime addingService(
+                            final ServiceReference<ServiceComponentRuntime> reference)
+                    {
+                        final ServiceComponentRuntime runtime = context.getService(reference);
+                        if ( runtime != null )
+                        {
+                            Hashtable props = new Hashtable();
+                            props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat ScrService");
+                            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+
+                            final ScrService service = new ScrServiceImpl(context, runtime);
+                            scrServiceRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
+                                    context.registerService(ScrService.class, service, props));
+
+                            props = new Hashtable();
+                            props.put(Constants.SERVICE_DESCRIPTION, "Apache Felix Compat SCR Info service");
+                            props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+                            final ScrInfo info = new ScrCommand(context, service);
+                            scrCommandRegMap.put((Long)reference.getProperty(Constants.SERVICE_ID),
+                                    context.registerService(ScrInfo.class, info, props));
+                        }
+                        return runtime;
+                    }
+
+                    public void modifiedService(
+                            final ServiceReference<ServiceComponentRuntime> reference,
+                            final ServiceComponentRuntime service) {
+                        // nothing to do
+                    }
+
+                    public void removedService(
+                            final ServiceReference<ServiceComponentRuntime> reference,
+                            final ServiceComponentRuntime service) {
+                        final ServiceRegistration<ScrService> reg =  scrServiceRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
+                        if ( reg != null )
+                        {
+                            reg.unregister();
+                        }
+                        final ServiceRegistration<ScrInfo> reg2 =  scrCommandRegMap.remove(reference.getProperty(Constants.SERVICE_ID));
+                        if ( reg2 != null )
+                        {
+                            reg2.unregister();
+                        }
+                        context.ungetService(reference);
+                    }
+        });
+        this.runtimeTracker.open();
+    }
+
+    public void stop(final BundleContext context) throws Exception
+    {
+        this.runtimeTracker.close();
+    }
+}
\ No newline at end of file
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
new file mode 100644
index 0000000..785c344
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrCommand.java
@@ -0,0 +1,477 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.compat;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.Reference;
+import org.apache.felix.scr.ScrInfo;
+import org.apache.felix.scr.ScrService;
+import org.apache.felix.scr.impl.config.ScrConfiguration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>ScrCommand</code> class provides the implementations for the
+ * Apache Felix Gogo and legacy Apache Felix Shell commands. The
+ * {@link #register(BundleContext, ScrService, ScrConfiguration)} method
+ * instantiates and registers the Gogo and Shell commands as possible.
+ */
+public class ScrCommand implements ScrInfo
+{
+
+    private final BundleContext bundleContext;
+    private final ScrService scrService;
+
+    public ScrCommand(final BundleContext bundleContext, final  ScrService scrService)
+    {
+        this.scrService = scrService;
+        this.bundleContext = bundleContext;
+
+    }
+
+    static boolean isBundleActive( final Bundle bundle )
+    {
+        if ( bundle != null )
+        {
+            if ( bundle.getState() == Bundle.ACTIVE )
+            {
+                return true;
+            }
+
+            if ( bundle.getState() == Bundle.STARTING )
+            {
+                // according to the spec the activationPolicy header is only
+                // set to request a bundle to be lazily activated. So in this
+                // simple check we just verify the header is set to assume
+                // the bundle is considered a lazily activated bundle
+                return bundle.getHeaders().get( Constants.BUNDLE_ACTIVATIONPOLICY ) != null;
+            }
+        }
+
+        // fall back: bundle is not considered active
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.impl.ScrInfo#list(java.lang.String, java.io.PrintStream, java.io.PrintStream)
+     */
+    public void list(final String bundleIdentifier, final PrintWriter out)
+    {
+        Component[] components;
+
+        if (bundleIdentifier != null)
+        {
+            Bundle bundle = null;
+            try
+            {
+                long bundleId = Long.parseLong(bundleIdentifier);
+                bundle = bundleContext.getBundle(bundleId);
+            }
+            catch (NumberFormatException nfe)
+            {
+                // might be a bundle symbolic name
+                Bundle[] bundles = bundleContext.getBundles();
+                for (int i = 0; i < bundles.length; i++)
+                {
+                    if (bundleIdentifier.equals(bundles[i].getSymbolicName()))
+                    {
+                        bundle = bundles[i];
+                        break;
+                    }
+                }
+            }
+
+            if (bundle == null)
+            {
+                throw new IllegalArgumentException("Missing bundle with ID " + bundleIdentifier);
+            }
+            if (isBundleActive(bundle))
+            {
+                components = scrService.getComponents(bundle);
+                if (components == null)
+                {
+                    out.println("Bundle " + bundleIdentifier + " declares no components");
+                    return;
+                }
+            }
+            else
+            {
+                out.println("Bundle " + bundleIdentifier + " is not active");
+                return;
+            }
+        }
+        else
+        {
+            components = scrService.getComponents();
+            if (components == null)
+            {
+                out.println("No components registered");
+                return;
+            }
+        }
+
+        Arrays.sort( components, new Comparator<Component>()
+                {
+
+                    public int compare(Component c1, Component c2)
+                    {
+                        return Long.signum(c1.getId() - c2.getId());
+                    }
+
+                });
+
+        out.println(" Id   State BundleId Name");
+        for ( Component component : components )
+        {
+            out.println( String.format( "[%1$4d] [%2$s] [%3$4d] %4$s", component.getId(), toStateString( component.getState() ), component.getBundle().getBundleId(), component.getName() ) );
+        }
+        out.flush();
+   }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.impl.ScrInfo#info(java.lang.String, java.io.PrintStream, java.io.PrintStream)
+     */
+    public void info(final String componentId, PrintWriter out)
+    {
+        Component[] components = getComponentFromArg(componentId);
+        if (components == null)
+        {
+            return;
+        }
+
+        Arrays.sort( components, new Comparator<Component>()
+                {
+
+                    public int compare(Component c1, Component c2)
+                    {
+                        long bundleId1 = c1.getBundle().getBundleId();
+                        long bundleId2 = c2.getBundle().getBundleId();
+                        int result = Long.signum(bundleId1 - bundleId2);
+                        if (result == 0) {
+                            result = Long.signum(c1.getId() - c2.getId());
+                        }
+                        return result;
+                    }
+
+                });
+
+        long bundleId = -1;
+
+        for ( Component component : components )
+        {
+            if (components.length > 1)
+            {
+                if ( component.getBundle().getBundleId() != bundleId )
+                {
+                    if ( bundleId != -1 )
+                    {
+                        out.println();
+                        out.println();
+                    }
+                    bundleId = component.getBundle().getBundleId();
+                    out.println(String.format("*** Bundle: %1$s (%2$d)", component.getBundle().getSymbolicName(), bundleId));
+                }
+                out.println();
+            }
+            out.print( "ID: " );
+            out.println( component.getId() );
+            out.print( "Name: " );
+            out.println( component.getName() );
+            out.print( "Bundle: " );
+            out.println( component.getBundle().getSymbolicName() + " (" + component.getBundle().getBundleId() + ")" );
+            out.print( "State: " );
+            out.println( toStateString( component.getState() ) );
+            out.print( "Default State: " );
+            out.println( component.isDefaultEnabled() ? "enabled" : "disabled" );
+            out.print( "Activation: " );
+            out.println( component.isImmediate() ? "immediate" : "delayed" );
+
+            // DS 1.1 new features
+            out.print( "Configuration Policy: " );
+            out.println( component.getConfigurationPolicy() );
+            out.print( "Activate Method: " );
+            out.print( component.getActivate() );
+            if ( component.isActivateDeclared() )
+            {
+                out.print( " (declared in the descriptor)" );
+            }
+            out.println();
+            out.print( "Deactivate Method: " );
+            out.print( component.getDeactivate() );
+            if ( component.isDeactivateDeclared() )
+            {
+                out.print( " (declared in the descriptor)" );
+            }
+            out.println();
+            out.print( "Modified Method: " );
+            if ( component.getModified() != null )
+            {
+                out.print( component.getModified() );
+            }
+            else
+            {
+                out.print( "-" );
+            }
+            out.println();
+
+            out.print( "Configuration Pid: " );
+            out.print( component.getConfigurationPid() );
+            if ( component.isConfigurationPidDeclared() )
+            {
+                out.print( " (declared in the descriptor)" );
+            }
+            out.println();
+
+            if ( component.getFactory() != null )
+            {
+                out.print( "Factory: " );
+                out.println( component.getFactory() );
+            }
+
+            String[] services = component.getServices();
+            if ( services != null )
+            {
+                out.print( "Services: " );
+                out.println( services[0] );
+                for ( int i = 1; i < services.length; i++ )
+                {
+                    out.print( "          " );
+                    out.println( services[i] );
+                }
+                out.print( "Service Type: " );
+                out.println( component.isServiceFactory() ? "service factory" : "service" );
+            }
+
+            Reference[] refs = component.getReferences();
+            if ( refs != null )
+            {
+                for ( Reference ref : refs )
+                {
+                    out.print( "Reference: " );
+                    out.println( ref.getName() );
+                    out.print( "    Satisfied: " );
+                    out.println( ref.isSatisfied() ? "satisfied" : "unsatisfied" );
+                    out.print( "    Service Name: " );
+                    out.println( ref.getServiceName() );
+                    if ( ref.getTarget() != null )
+                    {
+                        out.print( "    Target Filter: " );
+                        out.println( ref.getTarget() );
+                    }
+                    out.print( "    Multiple: " );
+                    out.println( ref.isMultiple() ? "multiple" : "single" );
+                    out.print( "    Optional: " );
+                    out.println( ref.isOptional() ? "optional" : "mandatory" );
+                    out.print( "    Policy: " );
+                    out.println( ref.isStatic() ? "static" : "dynamic" );
+                    out.print( "    Policy option: " );
+                    out.println( ref.isReluctant() ? "reluctant" : "greedy" );
+                    ServiceReference[] serviceRefs = ref.getServiceReferences();
+                    if ( serviceRefs != null )
+                    {
+                        out.print( "    Bound to:" );
+                        for ( int k = 0; k < serviceRefs.length; k++ )
+                        {
+                            out.print( "        " );
+                            out.println( serviceRefs[k] );
+                        }
+                    }
+                    else
+                    {
+                        out.println( "    (unbound)" );
+                    }
+                }
+            }
+
+            Dictionary props = component.getProperties();
+            if ( props != null )
+            {
+                out.println( "Properties:" );
+                TreeSet keys = new TreeSet( Collections.list( props.keys() ) );
+                for ( Object key : keys )
+                {
+                    out.print( "    " );
+                    out.print( key );
+                    out.print( " = " );
+
+                    Object prop = props.get( key );
+                    if ( prop.getClass().isArray() )
+                    {
+                        prop = Arrays.asList( ( Object[] ) prop );
+                    }
+                    out.print( prop );
+
+                    out.println();
+                }
+            }
+        }
+        out.flush();
+    }
+
+    void change(final String componentIdentifier, PrintWriter out, boolean enable)
+    {
+        Component[] components = getComponentFromArg(componentIdentifier);
+        ArrayList<String> disposed = new ArrayList<String>();
+        if (components == null)
+        {
+            return;
+        }
+
+        for ( Component component : components )
+        {
+            if ( component.getState() == Component.STATE_DISPOSED )
+            {
+                disposed.add(component.getName());
+            }
+            else if ( enable )
+            {
+                if ( component.getState() == Component.STATE_DISABLED )
+                {
+                    component.enable();
+                    out.println( "Component " + component.getName() + " enabled" );
+                }
+                else
+                {
+                    out.println( "Component " + component.getName() + " already enabled" );
+                }
+            }
+            else
+            {
+                if ( component.getState() != Component.STATE_DISABLED )
+                {
+                    component.disable();
+                    out.println( "Component " + component.getName() + " disabled" );
+                }
+                else
+                {
+                    out.println( "Component " + component.getName() + " already disabled" );
+                }
+            }
+        }
+        out.flush();
+        if ( !disposed.isEmpty() )
+        {
+            throw new IllegalArgumentException( "Components " + disposed + " already disposed, cannot change state" );
+
+        }
+    }
+
+    private String toStateString(int state)
+    {
+        switch (state) {
+
+        case (Component.STATE_DISABLED):
+            return "disabled    ";
+        case (Component.STATE_ENABLING):
+            return "enabling    ";
+        case (Component.STATE_ENABLED):
+            return "enabled     ";
+        case (Component.STATE_UNSATISFIED):
+            return "unsatisfied ";
+        case (Component.STATE_ACTIVATING):
+            return "activating  ";
+        case (Component.STATE_ACTIVE):
+            return "active      ";
+        case (Component.STATE_REGISTERED):
+            return "registered  ";
+        case (Component.STATE_FACTORY):
+            return "factory     ";
+        case (Component.STATE_DEACTIVATING):
+            return "deactivating";
+        case (Component.STATE_DISABLING):
+            return "disabling   ";
+        case (Component.STATE_DISPOSING):
+            return "disposing   ";
+        case (Component.STATE_DISPOSED):
+            return "disposed    ";
+        default:
+            return "unkown: " + state;
+        }
+    }
+
+    private Component[] getComponentFromArg(final String componentIdentifier)
+    {
+        Component[] components = null;
+        if (componentIdentifier != null)
+        {
+            try
+            {
+                long componentId = Long.parseLong(componentIdentifier);
+                Component component = scrService.getComponent(componentId);
+                if (component == null)
+                {
+                    throw new IllegalArgumentException("Missing Component with ID " + componentId);
+                }
+                else
+                {
+                    return new Component[]
+                        { component };
+                }
+            }
+            catch (NumberFormatException nfe)
+            {
+
+                // check whether it is a component name
+                components = scrService.getComponents(componentIdentifier);
+            }
+        }
+        if ( components == null)
+        {
+            components = scrService.getComponents();
+            if (componentIdentifier != null)
+            {
+                ArrayList<Component> cs = new ArrayList<Component>(components.length);
+                Pattern p = Pattern.compile(componentIdentifier);
+                for (Component component: components)
+                {
+                    if ( p.matcher( component.getName()).matches() )
+                    {
+                        cs.add( component );
+                    }
+                }
+                if (cs.isEmpty())
+                {
+                    throw new IllegalArgumentException("No Component with ID or matching " + componentIdentifier);
+                }
+                components = cs.toArray( new Component[cs.size()] );
+            }
+        }
+
+        return components;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.scr.impl.ScrInfo#config(java.io.PrintStream)
+     */
+    public void config(PrintWriter out)
+    {
+        out.println("Configuration not available.");
+    }
+}
diff --git a/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java
new file mode 100644
index 0000000..2ad5d64
--- /dev/null
+++ b/scr-compat/src/main/java/org/apache/felix/scr/impl/compat/ScrServiceImpl.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.compat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.Reference;
+import org.apache.felix.scr.ScrService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.service.component.ComponentInstance;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
+import org.osgi.service.component.runtime.dto.ReferenceDTO;
+import org.osgi.service.component.runtime.dto.SatisfiedReferenceDTO;
+
+public class ScrServiceImpl implements ScrService
+{
+
+	private static final String[] EMPTY = {};
+
+	private final BundleContext context;
+	private final ServiceComponentRuntime runtime;
+
+
+	public ScrServiceImpl(BundleContext context, final ServiceComponentRuntime runtime)
+	{
+        // we always use the system bundle to avoid problems if subsystems etc.
+        // are used and the SCR implemented extends those "invisible" bundles
+		this.context = context.getBundle(0).getBundleContext();
+		this.runtime = runtime;
+	}
+
+
+	// ScrService
+
+    /**
+     * @see org.apache.felix.scr.ScrService#getComponents()
+     */
+    public Component[] getComponents()
+    {
+        return this.getComponents((Bundle)null);
+    }
+
+
+    /**
+     * @see org.apache.felix.scr.ScrService#getComponents(org.osgi.framework.Bundle)
+     */
+    public Component[] getComponents( final Bundle bundle )
+    {
+        List<Component> result = new ArrayList<Component>();
+
+        final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs(bundle);
+        for(final ComponentDescriptionDTO descDTO : descriptions )
+        {
+            final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO);
+            ComponentConfigurationDTO configDTO = null;
+            if ( !configs.isEmpty() )
+            {
+                configDTO = configs.iterator().next();
+            }
+            result.add(new ComponentWrapper(this.context, this.runtime, descDTO, configDTO));
+        }
+
+        return result.isEmpty() ? null : result.toArray( new Component[result.size()] );
+    }
+
+
+    /**
+     * @see org.apache.felix.scr.ScrService#getComponent(long)
+     */
+    public Component getComponent( long componentId )
+    {
+        final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs();
+        for(final ComponentDescriptionDTO descDTO : descriptions )
+        {
+            final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO);
+            for(final ComponentConfigurationDTO configDTO : configs)
+            {
+                if ( configDTO.id == componentId )
+                {
+                    return new ComponentWrapper(this.context, this.runtime, descDTO, configDTO);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @see org.apache.felix.scr.ScrService#getComponents(java.lang.String)
+     */
+    public Component[] getComponents( final String componentName )
+    {
+        List<Component> result = new ArrayList<Component>();
+
+        final Collection<ComponentDescriptionDTO> descriptions = this.runtime.getComponentDescriptionDTOs();
+        for(final ComponentDescriptionDTO descDTO : descriptions )
+        {
+            if ( descDTO.name.equals(componentName) ) {
+                final Collection<ComponentConfigurationDTO> configs = this.runtime.getComponentConfigurationDTOs(descDTO);
+                ComponentConfigurationDTO configDTO = null;
+                if ( !configs.isEmpty() )
+                {
+                    configDTO = configs.iterator().next();
+                }
+                result.add(new ComponentWrapper(this.context, this.runtime, descDTO, configDTO));
+            }
+        }
+
+        return result.isEmpty() ? null : result.toArray( new Component[result.size()] );
+    }
+
+
+    private static final class ComponentWrapper implements Component
+    {
+        private final ComponentDescriptionDTO description;
+
+        private final ComponentConfigurationDTO configuration;
+
+        private final BundleContext bundleContext;
+
+        private final ServiceComponentRuntime runtime;
+
+        public ComponentWrapper(final BundleContext bundleContext,
+                final ServiceComponentRuntime runtime,
+                final ComponentDescriptionDTO description,
+                final ComponentConfigurationDTO configuration)
+        {
+            this.bundleContext = bundleContext;
+            this.description = description;
+            this.configuration = configuration;
+            this.runtime = runtime;
+        }
+
+        public long getId()
+        {
+            return configuration != null ? configuration.id : -1;
+        }
+
+        public String getName()
+        {
+            return description.name;
+        }
+
+        public int getState()
+        {
+            if ( configuration == null )
+            {
+                return Component.STATE_UNSATISFIED; // TODO Check!
+            }
+            final int s = configuration.state;
+            switch ( s )
+            {
+                case ComponentConfigurationDTO.ACTIVE : return Component.STATE_ACTIVE;
+                case ComponentConfigurationDTO.SATISFIED : return Component.STATE_ENABLED;
+                case ComponentConfigurationDTO.UNSATISFIED_CONFIGURATION : return Component.STATE_UNSATISFIED;
+                case ComponentConfigurationDTO.UNSATISFIED_REFERENCE : return Component.STATE_UNSATISFIED;
+                default: // satisfied
+                    return Component.STATE_ENABLED;
+            }
+        }
+
+        public Bundle getBundle()
+        {
+            return this.bundleContext.getBundle(this.description.bundle.id);
+        }
+
+        public String getFactory()
+        {
+            return this.description.factory;
+        }
+
+        public boolean isServiceFactory()
+        {
+            return false; // TODO
+        }
+
+        public String getClassName()
+        {
+            return this.description.implementationClass;
+        }
+
+        public boolean isDefaultEnabled()
+        {
+            return this.description.defaultEnabled;
+        }
+
+        public boolean isImmediate()
+        {
+            return this.description.immediate;
+        }
+
+        public String[] getServices()
+        {
+            return this.description.serviceInterfaces;
+        }
+
+        public Dictionary getProperties()
+        {
+            return new Hashtable<String, Object>(this.description.properties);
+        }
+
+        public Reference[] getReferences()
+        {
+            if ( this.configuration == null )
+            {
+                return null;
+            }
+
+            final List<Reference> result = new ArrayList<Reference>();
+            for(final ReferenceDTO dto : this.description.references)
+            {
+                SatisfiedReferenceDTO sRef = null;
+                for(final SatisfiedReferenceDTO r : this.configuration.satisfiedReferences)
+                {
+                    if ( r.name.equals(dto.name) )
+                    {
+                        sRef = r;
+                        break;
+                    }
+                }
+                result.add(new ReferenceWrapper(this.bundleContext, dto, sRef));
+            }
+
+            if ( result.isEmpty() )
+            {
+                return null;
+            }
+
+            return result.toArray(new Reference[result.size()]);
+        }
+
+        public ComponentInstance getComponentInstance()
+        {
+            // TODO - how do we want to enable this?
+            return null;
+        }
+
+        public String getActivate()
+        {
+            return this.description.activate;
+        }
+
+        public boolean isActivateDeclared()
+        {
+            return this.description.activate != null;
+        }
+
+        public String getDeactivate()
+        {
+            return this.description.deactivate;
+        }
+
+        public boolean isDeactivateDeclared()
+        {
+            return this.description.deactivate != null;
+        }
+
+        public String getModified()
+        {
+            return this.description.modified;
+        }
+
+        public String getConfigurationPolicy()
+        {
+            return this.description.configurationPolicy;
+        }
+
+        public String getConfigurationPid()
+        {
+            final String[] pids = this.description.configurationPid;
+            return pids[0];
+        }
+
+        public boolean isConfigurationPidDeclared()
+        {
+            return true;
+        }
+
+        public void enable()
+        {
+            this.runtime.enableComponent(this.description);
+        }
+
+        public void disable()
+        {
+            this.runtime.disableComponent(this.description);
+        }
+    }
+
+    private static final class ReferenceWrapper implements Reference
+    {
+        // constant for option single reference - 0..1
+        private static final String CARDINALITY_0_1 = "0..1";
+
+        // constant for option multiple reference - 0..n
+        private static final String CARDINALITY_0_N = "0..n";
+
+        // constant for required multiple reference - 1..n
+        private static final String CARDINALITY_1_N = "1..n";
+
+        // constant for static policy
+        private static final String POLICY_STATIC = "static";
+
+        // constant for reluctant policy option
+        private static final String POLICY_OPTION_RELUCTANT = "reluctant";
+
+        private final ReferenceDTO dto;
+
+        private final SatisfiedReferenceDTO satisfiedDTO;
+
+        private final BundleContext bundleContext;
+
+        public ReferenceWrapper(
+                final BundleContext bundleContext,
+                final ReferenceDTO dto,
+                final SatisfiedReferenceDTO satisfied)
+        {
+            this.bundleContext = bundleContext;
+            this.dto = dto;
+            this.satisfiedDTO = satisfied;
+        }
+
+        public String getName()
+        {
+            return dto.name;
+        }
+
+        public String getServiceName()
+        {
+            return dto.interfaceName;
+        }
+
+        public ServiceReference[] getServiceReferences()
+        {
+            if ( this.satisfiedDTO == null )
+            {
+                return null;
+            }
+            final List<ServiceReference<?>> refs = new ArrayList<ServiceReference<?>>();
+            for(ServiceReferenceDTO dto : this.satisfiedDTO.boundServices)
+            {
+                try
+                {
+                    final ServiceReference<?>[] serviceRefs = this.bundleContext.getServiceReferences((String)null,
+                            "(" + Constants.SERVICE_ID + "=" + String.valueOf(dto.id) + ")");
+                    if ( serviceRefs != null && serviceRefs.length > 0 )
+                    {
+                        refs.add(serviceRefs[0]);
+                    }
+                }
+                catch ( final InvalidSyntaxException ise)
+                {
+                    // ignore
+                }
+            }
+            return refs.toArray(new ServiceReference<?>[refs.size()]);
+        }
+
+        public ServiceReference<?>[] getBoundServiceReferences()
+        {
+            return this.getServiceReferences();
+        }
+
+        public boolean isSatisfied()
+        {
+            return this.satisfiedDTO != null;
+        }
+
+        public boolean isOptional()
+        {
+            return CARDINALITY_0_1.equals(dto.cardinality) || CARDINALITY_0_N.equals(dto.cardinality);
+        }
+
+        public boolean isMultiple()
+        {
+            return CARDINALITY_1_N.equals(dto.cardinality) || CARDINALITY_0_N.equals(dto.cardinality);
+        }
+
+        public boolean isStatic()
+        {
+            return POLICY_STATIC.equals(dto.policy);
+        }
+
+        public boolean isReluctant()
+        {
+            return POLICY_OPTION_RELUCTANT.equals(dto.policyOption);
+        }
+
+        public String getTarget()
+        {
+            return this.dto.target;
+        }
+
+        public String getBindMethodName()
+        {
+            return this.dto.bind;
+        }
+
+        public String getUnbindMethodName()
+        {
+            return this.dto.unbind;
+        }
+
+        public String getUpdatedMethodName()
+        {
+            return this.dto.unbind;
+        }
+    }
+}
