diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 280bc85..b9ac3ab 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -42,6 +42,7 @@
 import org.apache.felix.framework.util.ShrinkableCollection;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
+import org.osgi.dto.DTO;
 import org.osgi.framework.AdaptPermission;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
@@ -1114,6 +1115,11 @@
             return (A) new AccessControlContext(new ProtectionDomain[] {pd});
 
         }
+        else if (DTO.class.isAssignableFrom(type) ||
+                DTO[].class.isAssignableFrom(type))
+        {
+            return DTOFactory.createDTO(this, type);
+        }
         return null;
     }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/DTOFactory.java b/framework/src/main/java/org/apache/felix/framework/DTOFactory.java
new file mode 100644
index 0000000..e3cb64f
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/DTOFactory.java
@@ -0,0 +1,480 @@
+/*
+ * 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.framework;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.Version;
+import org.osgi.framework.dto.BundleDTO;
+import org.osgi.framework.dto.FrameworkDTO;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.startlevel.dto.BundleStartLevelDTO;
+import org.osgi.framework.startlevel.dto.FrameworkStartLevelDTO;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.dto.BundleRevisionDTO;
+import org.osgi.framework.wiring.dto.BundleWireDTO;
+import org.osgi.framework.wiring.dto.BundleWiringDTO;
+import org.osgi.framework.wiring.dto.BundleWiringDTO.NodeDTO;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.resource.dto.CapabilityDTO;
+import org.osgi.resource.dto.CapabilityRefDTO;
+import org.osgi.resource.dto.RequirementDTO;
+import org.osgi.resource.dto.RequirementRefDTO;
+import org.osgi.resource.dto.WireDTO;
+
+/**
+ * Creates various DTOs provided by the core framework.
+ */
+public class DTOFactory
+{
+    private DTOFactory()
+    {
+        // Only static methods
+    }
+
+    static <T> T createDTO(Bundle bundle, Class<T> type)
+    {
+        if (Bundle.UNINSTALLED == bundle.getState())
+            return null;
+
+        if (type == BundleDTO.class)
+        {
+            return type.cast(createBundleDTO(bundle));
+        }
+        else if (type == BundleStartLevelDTO.class)
+        {
+            return type.cast(createBundleStartLevelDTO(bundle));
+        }
+        else if (type == BundleRevisionDTO.class)
+        {
+            return type.cast(createBundleRevisionDTO(bundle));
+        }
+        else if (type == BundleRevisionDTO[].class)
+        {
+            return type.cast(createBundleRevisionDTOArray(bundle));
+        }
+        else if (type == BundleWiringDTO.class)
+        {
+            return type.cast(createBundleWiringDTO(bundle));
+        }
+        else if (type == BundleWiringDTO[].class)
+        {
+            return type.cast(createBundleWiringDTOArray(bundle));
+        }
+        else if (type == ServiceReferenceDTO[].class)
+        {
+            return type.cast(createServiceReferenceDTOArray(bundle));
+        }
+        else if (type == FrameworkDTO.class && bundle instanceof Felix)
+        {
+            return type.cast(createFrameworkDTO((Felix) bundle));
+        }
+        else if (type == FrameworkStartLevelDTO.class && bundle instanceof Framework)
+        {
+            return type.cast(createFrameworkStartLevelDTO((Framework) bundle));
+        }
+        return null;
+    }
+
+    private static BundleDTO createBundleDTO(Bundle bundle)
+    {
+        BundleDTO dto = new BundleDTO();
+        dto.id = bundle.getBundleId();
+        dto.lastModified = bundle.getLastModified();
+        dto.state = bundle.getState();
+        dto.symbolicName = bundle.getSymbolicName();
+        dto.version = "" + bundle.getVersion();
+        return dto;
+    }
+
+    private static BundleRevisionDTO createBundleRevisionDTO(Bundle bundle)
+    {
+        BundleRevision br = bundle.adapt(BundleRevision.class);
+        if (!(br instanceof BundleRevisionImpl))
+            return null;
+
+        return createBundleRevisionDTO(bundle, (BundleRevisionImpl) br, new HashSet<BundleRevisionDTO>());
+    }
+
+    private static BundleRevisionDTO[] createBundleRevisionDTOArray(Bundle bundle)
+    {
+        BundleRevisions brs = bundle.adapt(BundleRevisions.class);
+        if (brs == null || brs.getRevisions() == null)
+            return null;
+
+        List<BundleRevision> revisions = brs.getRevisions();
+        BundleRevisionDTO[] dtos = new BundleRevisionDTO[revisions.size()];
+        for (int i=0; i < revisions.size(); i++)
+        {
+            if (revisions.get(i) instanceof BundleRevisionImpl)
+                dtos[i] = createBundleRevisionDTO(bundle, (BundleRevisionImpl) revisions.get(i), new HashSet<BundleRevisionDTO>());
+        }
+        return dtos;
+    }
+
+    private static BundleRevisionDTO createBundleRevisionDTO(BundleRevision revision, Set<BundleRevisionDTO> resources)
+    {
+        if (revision instanceof BundleRevisionImpl)
+            return createBundleRevisionDTO(revision.getBundle(), (BundleRevisionImpl) revision, resources);
+        else
+            return null;
+    }
+
+    private static BundleRevisionDTO createBundleRevisionDTO(Bundle bundle, BundleRevisionImpl revision, Set<BundleRevisionDTO> resources)
+    {
+        BundleRevisionDTO dto = new BundleRevisionDTO();
+        dto.id = getRevisionID(revision);
+        addBundleRevisionDTO(dto, resources);
+
+        dto.bundle = bundle.getBundleId();
+        dto.symbolicName = revision.getSymbolicName();
+        dto.type = revision.getTypes();
+        dto.version = revision.getVersion().toString();
+
+        dto.capabilities = new ArrayList<CapabilityDTO>();
+        for (Capability cap : revision.getCapabilities(null))
+        {
+            CapabilityDTO cdto = new CapabilityDTO();
+            cdto.id = getCapabilityID(cap);
+            cdto.namespace = cap.getNamespace();
+            cdto.attributes = convertAttrsToDTO(cap.getAttributes());
+            cdto.directives = new HashMap<String, String>(cap.getDirectives());
+            cdto.resource = getResourceIDAndAdd(cap.getResource(), resources);
+
+            dto.capabilities.add(cdto);
+        }
+
+        dto.requirements = new ArrayList<RequirementDTO>();
+        for (Requirement req : revision.getRequirements(null))
+        {
+            RequirementDTO rdto = new RequirementDTO();
+            rdto.id = getRequirementID(req);
+            rdto.namespace = req.getNamespace();
+            rdto.attributes = convertAttrsToDTO(req.getAttributes());
+            rdto.directives = new HashMap<String, String>(req.getDirectives());
+            rdto.resource = getResourceIDAndAdd(req.getResource(), resources);
+
+            dto.requirements.add(rdto);
+        }
+        return dto;
+    }
+
+    private static BundleWiringDTO createBundleWiringDTO(Bundle bundle)
+    {
+        BundleWiring bw = bundle.adapt(BundleWiring.class);
+        return createBundleWiringDTO(bw);
+    }
+
+    private static BundleWiringDTO createBundleWiringDTO(BundleWiring wiring)
+    {
+        BundleWiringDTO dto = new BundleWiringDTO();
+        dto.bundle = wiring.getBundle().getBundleId();
+        dto.root = getWiringID(wiring);
+        dto.nodes = new HashSet<BundleWiringDTO.NodeDTO>();
+        dto.resources = new HashSet<BundleRevisionDTO>();
+
+        createBundleRevisionDTO(wiring.getRevision(), dto.resources);
+        createBundleWiringNodeDTO(wiring, dto.resources, dto.nodes);
+
+        return dto;
+    }
+
+    private static BundleWiringDTO[] createBundleWiringDTOArray(Bundle bundle)
+    {
+        BundleRevisions brs = bundle.adapt(BundleRevisions.class);
+        if (brs == null || brs.getRevisions() == null)
+            return null;
+
+        List<BundleRevision> revisions = brs.getRevisions();
+        BundleWiringDTO[] dtos = new BundleWiringDTO[revisions.size()];
+        for (int i=0; i < revisions.size(); i++)
+        {
+            BundleWiring wiring = revisions.get(i).getWiring();
+            dtos[i] = createBundleWiringDTO(wiring);
+        }
+        return dtos;
+    }
+
+    private static void createBundleWiringNodeDTO(BundleWiring bw, Set<BundleRevisionDTO> resources, Set<NodeDTO> nodes)
+    {
+        NodeDTO node = new BundleWiringDTO.NodeDTO();
+        node.id = getWiringID(bw);
+        nodes.add(node);
+
+        node.current = bw.isCurrent();
+        node.inUse = bw.isInUse();
+        node.resource = getResourceIDAndAdd(bw.getResource(), resources);
+
+        node.capabilities = new ArrayList<CapabilityRefDTO>();
+        for (Capability cap : bw.getCapabilities(null))
+        {
+            CapabilityRefDTO cdto = new CapabilityRefDTO();
+            cdto.capability = getCapabilityID(cap);
+            cdto.resource = getResourceIDAndAdd(cap.getResource(), resources);
+            node.capabilities.add(cdto);
+        }
+
+        node.requirements = new ArrayList<RequirementRefDTO>();
+        for (Requirement req : bw.getRequirements(null))
+        {
+            RequirementRefDTO rdto = new RequirementRefDTO();
+            rdto.requirement = getRequirementID(req);
+            rdto.resource = getResourceIDAndAdd(req.getResource(), resources);
+            node.requirements.add(rdto);
+        }
+
+        node.providedWires = new ArrayList<WireDTO>();
+        for (Wire pw : bw.getProvidedWires(null))
+        {
+            node.providedWires.add(createBundleWireDTO(pw, resources, nodes));
+        }
+
+        node.requiredWires = new ArrayList<WireDTO>();
+        for (Wire rw : bw.getRequiredWires(null))
+        {
+            node.requiredWires.add(createBundleWireDTO(rw, resources, nodes));
+        }
+    }
+
+    private static BundleWireDTO createBundleWireDTO(Wire wire, Set<BundleRevisionDTO> resources, Set<NodeDTO> nodes)
+    {
+        BundleWireDTO wdto = new BundleWireDTO();
+        if (wire instanceof BundleWire)
+        {
+            BundleWire w = (BundleWire) wire;
+
+            BundleWiring pw = w.getProviderWiring();
+            addWiringNodeIfNotPresent(pw, resources, nodes);
+            wdto.providerWiring = getWiringID(pw);
+
+            BundleWiring rw = w.getRequirerWiring();
+            addWiringNodeIfNotPresent(rw, resources, nodes);
+            wdto.requirerWiring = getWiringID(rw);
+        }
+        wdto.provider = getResourceIDAndAdd(wire.getProvider(), resources);
+        wdto.requirer = getResourceIDAndAdd(wire.getRequirer(), resources);
+        wdto.capability = new CapabilityRefDTO();
+        wdto.capability.capability = getCapabilityID(wire.getCapability());
+        wdto.capability.resource = getResourceIDAndAdd(wire.getCapability().getResource(), resources);
+        wdto.requirement = new RequirementRefDTO();
+        wdto.requirement.requirement = getRequirementID(wire.getRequirement());
+        wdto.requirement.resource = getResourceIDAndAdd(wire.getRequirement().getResource(), resources);
+        return wdto;
+    }
+
+    private static BundleStartLevelDTO createBundleStartLevelDTO(Bundle bundle)
+    {
+        BundleStartLevelDTO dto = new BundleStartLevelDTO();
+        dto.bundle = bundle.getBundleId();
+
+        BundleStartLevel sl = bundle.adapt(BundleStartLevel.class);
+        dto.activationPolicyUsed = sl.isActivationPolicyUsed();
+        dto.persistentlyStarted = sl.isPersistentlyStarted();
+        dto.startLevel = sl.getStartLevel();
+
+        return dto;
+    }
+
+    private static ServiceReferenceDTO[] createServiceReferenceDTOArray(Bundle bundle)
+    {
+        BundleContext ctx = bundle.getBundleContext();
+        if (ctx == null)
+            return null;
+
+        ServiceReference<?>[] svcs = bundle.getRegisteredServices();
+        if (svcs == null)
+            return new ServiceReferenceDTO[0];
+
+        ServiceReferenceDTO[] dtos = new ServiceReferenceDTO[svcs.length];
+        for (int i=0; i < svcs.length; i++)
+        {
+            dtos[i] = createServiceReferenceDTO(svcs[i]);
+        }
+        return dtos;
+    }
+
+    private static ServiceReferenceDTO createServiceReferenceDTO(ServiceReference<?> svc)
+    {
+        ServiceReferenceDTO dto = new ServiceReferenceDTO();
+        dto.bundle = svc.getBundle().getBundleId();
+        dto.id = (Long) svc.getProperty(Constants.SERVICE_ID);
+        Map<String, Object> props = new HashMap<String, Object>();
+        for (String key : svc.getPropertyKeys())
+        {
+            props.put(key, svc.getProperty(key));
+        }
+        dto.properties = new HashMap<String, Object>(props);
+
+        Bundle[] ubs = svc.getUsingBundles();
+        if (ubs == null)
+        {
+            dto.usingBundles = new long[0];
+        }
+        else
+        {
+            dto.usingBundles = new long[ubs.length];
+            for (int j=0; j < ubs.length; j++)
+            {
+                dto.usingBundles[j] = ubs[j].getBundleId();
+            }
+        }
+        return dto;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static FrameworkDTO createFrameworkDTO(Felix framework)
+    {
+        FrameworkDTO dto = new FrameworkDTO();
+        dto.properties = framework.getConfig(); // This map is immutable, so it's fine to share
+
+        dto.bundles = new ArrayList<BundleDTO>();
+        for (Bundle b : framework.getBundleContext().getBundles())
+        {
+            dto.bundles.add(DTOFactory.createDTO(b, BundleDTO.class));
+        }
+
+        dto.services = new ArrayList<ServiceReferenceDTO>();
+
+        ServiceReference<?>[] refs = null;
+        try
+        {
+            refs = framework.getBundleContext().getAllServiceReferences(null, null);
+        }
+        catch (InvalidSyntaxException e)
+        {
+            // No filter, should never happen
+        }
+
+        for (ServiceReference<?> sr : refs)
+        {
+            dto.services.add(createServiceReferenceDTO(sr));
+        }
+
+        return dto;
+    }
+
+    private static FrameworkStartLevelDTO createFrameworkStartLevelDTO(Framework framework)
+    {
+        FrameworkStartLevel fsl = framework.adapt(FrameworkStartLevel.class);
+
+        FrameworkStartLevelDTO dto = new FrameworkStartLevelDTO();
+        dto.initialBundleStartLevel = fsl.getInitialBundleStartLevel();
+        dto.startLevel = fsl.getStartLevel();
+
+        return dto;
+    }
+
+    private static void addBundleRevisionDTO(BundleRevisionDTO dto, Set<BundleRevisionDTO> resources)
+    {
+        for (BundleRevisionDTO r : resources)
+        {
+            if (r.id == dto.id)
+                return;
+        }
+        resources.add(dto);
+    }
+
+    private static void addWiringNodeIfNotPresent(BundleWiring bw, Set<BundleRevisionDTO> resources, Set<NodeDTO> nodes)
+    {
+        int wiringID = getWiringID(bw);
+        for (NodeDTO n : nodes)
+        {
+            if (n.id == wiringID)
+                return;
+        }
+        createBundleWiringNodeDTO(bw, resources, nodes);
+    }
+
+    // Attributes contain Version values which are not supported for DTOs, so if
+    // these are found they need to be converted to String values.
+    private static Map<String, Object> convertAttrsToDTO(Map<String, Object> map)
+    {
+        Map<String, Object> m = new HashMap<String, Object>();
+        for (Map.Entry<String, Object> entry : map.entrySet())
+        {
+            if (entry.getValue() instanceof Version)
+                // DTOs don't support Version objects
+                m.put(entry.getKey(), entry.getValue().toString());
+            else
+                m.put(entry.getKey(), entry.getValue());
+        }
+        return m;
+    }
+
+    private static int getWiringID(Wiring bw)
+    {
+        return bw.hashCode();
+    }
+
+    private static int getCapabilityID(Capability capability)
+    {
+        return capability.hashCode();
+    }
+
+    private static int getRequirementID(Requirement requirement)
+    {
+        return requirement.hashCode();
+    }
+
+    private static int getResourceIDAndAdd(Resource res, Set<BundleRevisionDTO> resources)
+    {
+        if (res instanceof BundleRevisionImpl)
+        {
+            BundleRevisionImpl bres = (BundleRevisionImpl) res;
+            int id = bres.getId().hashCode();
+
+            if (resources == null)
+                return id;
+
+            for (BundleRevisionDTO rdto : resources)
+            {
+                if (rdto.id == id)
+                    return id;
+            }
+            createBundleRevisionDTO(bres, resources);
+            return id;
+        }
+        return res.hashCode();
+    }
+
+    private static int getRevisionID(BundleRevisionImpl revision)
+    {
+        return revision.getId().hashCode();
+    }
+}
diff --git a/framework/src/test/java/org/apache/felix/framework/DTOFactoryTest.java b/framework/src/test/java/org/apache/felix/framework/DTOFactoryTest.java
new file mode 100644
index 0000000..fc897bf
--- /dev/null
+++ b/framework/src/test/java/org/apache/felix/framework/DTOFactoryTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.framework;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.felix.framework.Felix;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.dto.ServiceReferenceDTO;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.startlevel.dto.BundleStartLevelDTO;
+import org.osgi.framework.wiring.dto.BundleRevisionDTO;
+import org.osgi.framework.wiring.dto.BundleWiringDTO;
+import org.osgi.resource.dto.CapabilityDTO;
+
+public class DTOFactoryTest
+{
+    private int counter;
+    private Framework framework;
+    private File testDir;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        String path = "/" + getClass().getName().replace('.', '/') + ".class";
+        String url = getClass().getResource(path).getFile();
+        String baseDir = url.substring(0, url.length() - path.length());
+        String rndStr = Long.toString(System.nanoTime(), Character.MAX_RADIX);
+        rndStr = rndStr.substring(rndStr.length() - 6, rndStr.length() - 1);
+        testDir = new File(baseDir, getClass().getSimpleName() + "_" + rndStr);
+
+        File cacheDir = new File(testDir, "cache");
+        cacheDir.mkdirs();
+        String cache = cacheDir.getAbsolutePath();
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("felix.cache.profiledir", cache);
+        params.put("felix.cache.dir", cache);
+        params.put(Constants.FRAMEWORK_STORAGE, cache);
+
+        framework = new Felix(params);
+        framework.init();
+        framework.start();
+    }
+
+    @After
+    public void tearDown() throws Exception
+    {
+        framework.stop();
+    }
+
+    @Test
+    public void testBundleStartLevelDTO() throws Exception
+    {
+        String mf = "Bundle-SymbolicName: tb1\n"
+                + "Bundle-Version: 1.0.0\n"
+                + "Bundle-ManifestVersion: 2\n";
+        File bf = createBundle(mf);
+        Bundle bundle = framework.getBundleContext().installBundle(bf.toURI().toURL().toExternalForm());
+
+        BundleStartLevel sl = bundle.adapt(BundleStartLevel.class);
+        sl.setStartLevel(7);
+
+        BundleStartLevelDTO dto = bundle.adapt(BundleStartLevelDTO.class);
+        assertEquals(bundle.getBundleId(), dto.bundle);
+        assertEquals(7, dto.startLevel);
+    }
+
+    @Test
+    public void testServiceReferenceDTOArray() throws Exception
+    {
+        ServiceRegistration<String> reg = framework.getBundleContext().registerService(String.class, "hi", null);
+        Long sid = (Long) reg.getReference().getProperty(Constants.SERVICE_ID);
+
+        ServiceReferenceDTO[] dtos = framework.adapt(ServiceReferenceDTO[].class);
+        assertTrue(dtos.length > 0);
+
+        boolean found = false;
+        for (ServiceReferenceDTO dto : dtos)
+        {
+            if (dto.id == sid)
+            {
+                found = true;
+                assertEquals(0L, dto.bundle);
+                assertEquals(sid, dto.properties.get(Constants.SERVICE_ID));
+                assertTrue(Arrays.equals(new String [] {String.class.getName()},
+                        (String []) dto.properties.get(Constants.OBJECTCLASS)));
+                assertEquals(0L, dto.properties.get(Constants.SERVICE_BUNDLEID));
+                assertEquals(Constants.SCOPE_SINGLETON, dto.properties.get(Constants.SERVICE_SCOPE));
+                assertEquals(0, dto.usingBundles.length);
+            }
+        }
+        assertTrue(found);
+    }
+
+    @Test
+    public void testBundleRevisionDTO() throws Exception
+    {
+        String mf = "Bundle-SymbolicName: tb2\n"
+                + "Bundle-Version: 1.2.3\n"
+                + "Bundle-ManifestVersion: 2\n"
+                + "Import-Package: org.osgi.framework;version=\"[1.1,2)\"";
+        File bf = createBundle(mf);
+        Bundle bundle = framework.getBundleContext().installBundle(bf.toURI().toURL().toExternalForm());
+        bundle.start();
+        assertEquals("Precondition", Bundle.ACTIVE, bundle.getState());
+
+        BundleRevisionDTO dto = bundle.adapt(BundleRevisionDTO.class);
+        assertEquals(bundle.getBundleId(), dto.bundle);
+        assertTrue(dto.id != 0);
+        assertEquals("tb2", dto.symbolicName);
+        assertEquals("1.2.3", dto.version);
+        assertEquals(0, dto.type);
+
+        boolean foundBundle = false;
+        boolean foundHost = false;
+        boolean foundIdentity = false;
+        int resource = 0;
+        for (CapabilityDTO cap : dto.capabilities)
+        {
+            assertTrue(cap.id != 0);
+            if (resource == 0)
+                resource = cap.resource;
+            else
+                assertEquals(resource, cap.resource);
+
+            if (BundleNamespace.BUNDLE_NAMESPACE.equals(cap.namespace))
+            {
+                foundBundle = true;
+                assertEquals("tb2", cap.attributes.get(BundleNamespace.BUNDLE_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE));
+            }
+            else if (HostNamespace.HOST_NAMESPACE.equals(cap.namespace))
+            {
+                foundHost = true;
+                assertEquals("tb2", cap.attributes.get(HostNamespace.HOST_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE));
+            }
+            else if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.namespace))
+            {
+                foundIdentity = true;
+                assertEquals("tb2", cap.attributes.get(IdentityNamespace.IDENTITY_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE));
+                assertEquals(IdentityNamespace.TYPE_BUNDLE, cap.attributes.get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+            }
+        }
+        assertTrue(foundBundle);
+        assertTrue(foundHost);
+        assertTrue(foundIdentity);
+    }
+
+    @Test
+    public void testBundleRevisionDTOArray() throws Exception {
+        String mf = "Bundle-SymbolicName: tb2\n"
+                + "Bundle-Version: 1.2.3\n"
+                + "Bundle-ManifestVersion: 2\n"
+                + "Import-Package: org.osgi.framework;version=\"[1.1,2)\"";
+        File bf = createBundle(mf);
+        Bundle bundle = framework.getBundleContext().installBundle(bf.toURI().toURL().toExternalForm());
+        bundle.start();
+        assertEquals("Precondition", Bundle.ACTIVE, bundle.getState());
+
+        BundleRevisionDTO[] dtos = bundle.adapt(BundleRevisionDTO[].class);
+        assertEquals(1, dtos.length);
+        BundleRevisionDTO dto = dtos[0];
+
+        assertEquals(bundle.getBundleId(), dto.bundle);
+        assertTrue(dto.id != 0);
+        assertEquals("tb2", dto.symbolicName);
+        assertEquals("1.2.3", dto.version);
+        assertEquals(0, dto.type);
+
+        boolean foundBundle = false;
+        boolean foundHost = false;
+        boolean foundIdentity = false;
+        int resource = 0;
+        for (CapabilityDTO cap : dto.capabilities)
+        {
+            assertTrue(cap.id != 0);
+            if (resource == 0)
+                resource = cap.resource;
+            else
+                assertEquals(resource, cap.resource);
+
+            if (BundleNamespace.BUNDLE_NAMESPACE.equals(cap.namespace))
+            {
+                foundBundle = true;
+                assertEquals("tb2", cap.attributes.get(BundleNamespace.BUNDLE_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE));
+            }
+            else if (HostNamespace.HOST_NAMESPACE.equals(cap.namespace))
+            {
+                foundHost = true;
+                assertEquals("tb2", cap.attributes.get(HostNamespace.HOST_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(HostNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE));
+            }
+            else if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.namespace))
+            {
+                foundIdentity = true;
+                assertEquals("tb2", cap.attributes.get(IdentityNamespace.IDENTITY_NAMESPACE));
+                assertEquals("1.2.3", cap.attributes.get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE));
+                assertEquals(IdentityNamespace.TYPE_BUNDLE, cap.attributes.get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+            }
+        }
+        assertTrue(foundBundle);
+        assertTrue(foundHost);
+        assertTrue(foundIdentity);
+    }
+
+    @Test
+    public void testBundleWiringDTO() throws Exception {
+        String mf = "Bundle-SymbolicName: tb2\n"
+                + "Bundle-Version: 1.2.3\n"
+                + "Bundle-ManifestVersion: 2\n"
+                + "Import-Package: org.osgi.framework;version=\"[1.1,2)\"";
+        File bf = createBundle(mf);
+        Bundle bundle = framework.getBundleContext().installBundle(bf.toURI().toURL().toExternalForm());
+        bundle.start();
+        assertEquals("Precondition", Bundle.ACTIVE, bundle.getState());
+
+        BundleWiringDTO dto = bundle.adapt(BundleWiringDTO.class);
+        assertEquals(bundle.getBundleId(), dto.bundle);
+    }
+
+    private File createBundle(String manifest) throws IOException
+    {
+        File f = File.createTempFile("felix-bundle" + counter++, ".jar", testDir);
+
+        Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8")));
+        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+
+        os.close();
+        return f;
+    }
+}
