diff --git a/framework/pom.xml b/framework/pom.xml
index 18f10e3..240fe2f 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -27,8 +27,7 @@
   <packaging>bundle</packaging>
   <name>Apache Felix Framework</name>
   <artifactId>org.apache.felix.framework</artifactId>
-  <version>4.7.0-SNAPSHOT</version>
-
+  <version>4.9.0-SNAPSHOT</version>
   <properties>
     <dollar>$</dollar>
   </properties>
@@ -68,7 +67,7 @@
                 org.osgi.util.tracker,
                 org.osgi.dto
             </Export-Package>
-            <Private-Package>org.apache.felix.framework.*</Private-Package>
+            <Private-Package>org.apache.felix.framework.*, org.apache.felix.resolver.*</Private-Package>
             <Import-Package>!*</Import-Package>
           </instructions>
         </configuration>
@@ -131,6 +130,12 @@
        <scope>provided</scope>
     </dependency>
     <dependency>
+       <groupId>org.apache.felix</groupId>
+       <artifactId>org.apache.felix.resolver</artifactId>
+       <version>1.1.0-SNAPSHOT</version>
+       <scope>provided</scope>
+    </dependency>
+    <dependency>
         <groupId>org.ow2.asm</groupId>
         <artifactId>asm-all</artifactId>
         <version>4.2</version>
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 b9ac3ab..35cf90d 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -1023,6 +1023,11 @@
                 AdminPermission.LIFECYCLE));
         }
 
+        Map headers = getCurrentLocalizedHeader(Locale.getDefault().toString());
+
+        // Uninstall the bundle.
+        getFramework().uninstallBundle(this);
+
         // After a bundle is uninstalled, the spec says getHeaders() should
         // return the localized headers for the default locale at the time of
         // of uninstall. So, let's clear the existing header cache to throw
@@ -1035,13 +1040,10 @@
         {
             if (m_uninstalledHeaders == null)
             {
-                m_uninstalledHeaders = getCurrentLocalizedHeader(Locale.getDefault().toString());
+                m_uninstalledHeaders = headers;
                 m_cachedHeaders.clear();
             }
         }
-
-        // Uninstall the bundle.
-        getFramework().uninstallBundle(this);
     }
 
     private static final SecurityManagerEx m_smEx = new SecurityManagerEx();
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
index 01bf4b8..ee5651d 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -674,6 +674,6 @@
     @Override
     public String toString()
     {
-        return m_id;
+        return m_bundle.toString() + "(R " + m_id + ")";
     }
 }
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index 8e984cd..80858b3 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -44,7 +44,6 @@
 import org.apache.felix.framework.cache.Content;
 import org.apache.felix.framework.cache.JarContent;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.resolver.ResolveException;
 import org.apache.felix.framework.resolver.ResourceNotFoundException;
 import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.FelixConstants;
@@ -75,6 +74,7 @@
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Wire;
+import org.osgi.service.resolver.ResolutionException;
 
 public class BundleWiringImpl implements BundleWiring
 {
@@ -1210,7 +1210,7 @@
             {
                 provider = m_resolver.resolve(m_revision, pkgName);
             }
-            catch (ResolveException ex)
+            catch (ResolutionException ex)
             {
                 // Ignore this since it is likely normal.
             }
@@ -1635,7 +1635,7 @@
         {
             provider = m_resolver.resolve(m_revision, pkgName);
         }
-        catch (ResolveException ex)
+        catch (ResolutionException ex)
         {
             // Ignore this since it is likely normal.
         }
@@ -2810,7 +2810,7 @@
             }
 
             String exporter = (exporters.isEmpty())
-                ? null : exporters.iterator().next().getRevision().getBundle().toString();
+                ? null : exporters.iterator().next().toString();
 
             StringBuffer sb = new StringBuffer("*** Class '");
             sb.append(name);
@@ -2855,7 +2855,7 @@
                 // Ignore
             }
 
-            String exporter = exports.iterator().next().getRevision().getBundle().toString();
+            String exporter = exports.iterator().next().toString();
 
             StringBuffer sb = new StringBuffer("*** Class '");
             sb.append(name);
diff --git a/framework/src/main/java/org/apache/felix/framework/DTOFactory.java b/framework/src/main/java/org/apache/felix/framework/DTOFactory.java
index e3cb64f..99cb8e7 100644
--- a/framework/src/main/java/org/apache/felix/framework/DTOFactory.java
+++ b/framework/src/main/java/org/apache/felix/framework/DTOFactory.java
@@ -313,10 +313,6 @@
 
     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];
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index c6b305a..d02d27a 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -57,7 +57,6 @@
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.ext.SecurityProvider;
-import org.apache.felix.framework.resolver.ResolveException;
 import org.apache.felix.framework.util.EventDispatcher;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.ListenerInfo;
@@ -102,6 +101,7 @@
 import org.osgi.framework.wiring.FrameworkWiring;
 import org.osgi.resource.Requirement;
 import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.resolver.ResolutionException;
 
 public class Felix extends BundleImpl implements Framework
 {
@@ -412,8 +412,16 @@
         // Create default bundle stream handler.
         m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
 
+        // Create service registry.
+        m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
+            public void serviceChanged(ServiceEvent event, Dictionary oldProps)
+            {
+                fireServiceEvent(event, oldProps);
+            }
+        });
+
         // Create a resolver and its state.
-        m_resolver = new StatefulResolver(this);
+        m_resolver = new StatefulResolver(this, m_registry);
 
         // Create the extension manager, which we will use as the
         // revision for the system bundle.
@@ -429,14 +437,6 @@
             throw new RuntimeException(ex.getMessage());
         }
 
-        // Create service registry.
-        m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
-            public void serviceChanged(ServiceEvent event, Dictionary oldProps)
-            {
-                fireServiceEvent(event, oldProps);
-            }
-        });
-
         // Create event dispatcher.
         m_dispatcher = new EventDispatcher(m_logger, m_registry);
 
@@ -734,12 +734,12 @@
                         Collections.singleton(adapt(BundleRevision.class)),
                         Collections.EMPTY_SET);
                 }
-                catch (ResolveException ex)
+                catch (ResolutionException ex)
                 {
                     // This should never happen.
                     throw new BundleException(
                         "Unresolved constraint in System Bundle:"
-                        + ex.getRequirement());
+                        + ex.getUnresolvedRequirements());
                 }
 
                 // Reload the cached bundles before creating and starting the
@@ -833,6 +833,7 @@
                 }
 
                 // Start services
+                m_resolver.start();
                 m_fwkWiring.start();
                 m_fwkStartLevel.start();
 
@@ -4062,7 +4063,7 @@
                         }
                     }
                 }
-                catch (ResolveException ex)
+                catch (ResolutionException ex)
                 {
                     result = false;
                 }
@@ -4087,19 +4088,11 @@
         {
             m_resolver.resolve(Collections.singleton(revision), Collections.EMPTY_SET);
         }
-        catch (ResolveException ex)
+        catch (ResolutionException ex)
         {
-            if (ex.getRevision() != null)
-            {
-                Bundle b = ex.getRevision().getBundle();
-                throw new BundleException(
-                    "Unresolved constraint in bundle "
-                    + b + ": " + ex.getMessage(), BundleException.RESOLVE_ERROR);
-            }
-            else
-            {
-                throw new BundleException(ex.getMessage(), BundleException.RESOLVE_ERROR);
-            }
+            throw new BundleException(ex.getMessage() +
+                " Unresolved requirements: " + ex.getUnresolvedRequirements(),
+                BundleException.RESOLVE_ERROR);
         }
     }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/Logger.java b/framework/src/main/java/org/apache/felix/framework/Logger.java
index 6e05d4f..42f3b13 100644
--- a/framework/src/main/java/org/apache/felix/framework/Logger.java
+++ b/framework/src/main/java/org/apache/felix/framework/Logger.java
@@ -20,7 +20,14 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import org.osgi.framework.*;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
 
 /**
  * <p>
@@ -41,14 +48,9 @@
  * the log service's method to avoid a dependency on the log interface.
  * </p>
 **/
-public class Logger implements ServiceListener
+public class Logger extends org.apache.felix.resolver.Logger implements ServiceListener
 {
-    public static final int LOG_ERROR = 1;
-    public static final int LOG_WARNING = 2;
-    public static final int LOG_INFO = 3;
-    public static final int LOG_DEBUG = 4;
-
-    private int m_logLevel = 1;
+    // TODO see if this class can be cleaned up a little more
     private BundleContext m_context = null;
 
     private final static int LOGGER_OBJECT_IDX = 0;
@@ -58,42 +60,23 @@
 
     public Logger()
     {
-    }
-
-    public final synchronized void setLogLevel(int i)
-    {
-        m_logLevel = i;
-    }
-
-    public final synchronized int getLogLevel()
-    {
-        return m_logLevel;
+        super(LOG_ERROR);
     }
 
     protected void setSystemBundleContext(BundleContext context)
     {
         // TODO: Find a way to log to a log service inside the framework.
         // The issue is that we log messages while holding framework
-        // internal locks -- hence, when a log service calls back into 
-        // the framework (e.g., by loading a class) we might deadlock. 
+        // internal locks -- hence, when a log service calls back into
+        // the framework (e.g., by loading a class) we might deadlock.
         // One instance of this problem is tracked in FELIX-536.
         // For now we just disable logging to log services inside the
-        // framework. 
+        // framework.
 
         // m_context = context;
         // startListeningForLogService();
     }
 
-    public final void log(int level, String msg)
-    {
-        _log(null, null, level, msg, null);
-    }
-
-    public final void log(int level, String msg, Throwable throwable)
-    {
-        _log(null, null, level, msg, throwable);
-    }
-
     public final void log(ServiceReference sr, int level, String msg)
     {
         _log(null, sr, level, msg, null);
@@ -168,7 +151,7 @@
         // more conservative locking here, but let's be optimistic.
         Object[] logger = m_logger;
 
-        if (m_logLevel >= level)
+        if (getLogLevel() >= level)
         {
             // Use the log service if available.
             if (logger != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
index 270da4f..bca43b4 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
@@ -26,29 +26,32 @@
 
 import org.apache.felix.framework.StatefulResolver.ResolverHookRecord;
 import org.apache.felix.framework.resolver.CandidateComparator;
-import org.apache.felix.framework.resolver.HostedCapability;
-import org.apache.felix.framework.resolver.ResolveContext;
-import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.resolver.FelixResolveContext;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolveContext;
 
 /**
  *
  * @author rickhall
  */
-public class ResolveContextImpl extends ResolveContext
+public class ResolveContextImpl extends ResolveContext implements FelixResolveContext
 {
     private final StatefulResolver m_state;
-    private final Map<BundleRevision, BundleWiring> m_wirings;
+    private final Map<Resource, Wiring> m_wirings;
     private final ResolverHookRecord m_resolverHookrecord;
     private final Collection<BundleRevision> m_mandatory;
     private final Collection<BundleRevision> m_optional;
     private final Collection<BundleRevision> m_ondemand;
 
     ResolveContextImpl(
-        StatefulResolver state, Map<BundleRevision, BundleWiring> wirings,
+        StatefulResolver state, Map<Resource, Wiring> wirings,
         ResolverHookRecord resolverHookRecord, Collection<BundleRevision> mandatory,
         Collection<BundleRevision> optional, Collection<BundleRevision> ondemand)
     {
@@ -61,30 +64,41 @@
     }
 
     @Override
-    public Collection<BundleRevision> getMandatoryRevisions()
+    public Collection<Resource> getMandatoryResources()
     {
-        return new ArrayList<BundleRevision>(m_mandatory);
+        return new ArrayList<Resource>(m_mandatory);
     }
 
     @Override
-    public Collection<BundleRevision> getOptionalRevisions()
+    public Collection<Resource> getOptionalResources()
     {
-        return new ArrayList<BundleRevision>(m_optional);
+        return new ArrayList<Resource>(m_optional);
     }
 
-    public Collection<BundleRevision> getOndemandRevisions()
+    public Collection<Resource> getOndemandResources(Resource host)
     {
-        return new ArrayList<BundleRevision>(m_ondemand);
+        return new ArrayList<Resource>(m_ondemand);
     }
 
     @Override
-    public List<BundleCapability> findProviders(BundleRequirement br, boolean obeyMandatory)
+    public List<Capability> findProviders(Requirement br)
     {
-        return m_state.findProvidersInternal(m_resolverHookrecord, br, obeyMandatory, true);
+        if (!(br instanceof BundleRequirement))
+            throw new IllegalStateException("Expected a BundleRequirement");
+
+        List<BundleCapability> result = m_state.findProvidersInternal(
+            m_resolverHookrecord, br, true, true);
+
+        // Casting the result to a List of Capability.
+        // TODO Can we do this without the strang double-cast?
+        @SuppressWarnings("unchecked")
+        List<Capability> caps =
+            (List<Capability>) (List<? extends Capability>) result;
+        return caps;
     }
 
     @Override
-    public int insertHostedCapability(List<BundleCapability> caps, HostedCapability hc)
+    public int insertHostedCapability(List<Capability> caps, HostedCapability hc)
     {
         int idx = Collections.binarySearch(caps, hc, new CandidateComparator());
         if (idx < 0)
@@ -96,19 +110,14 @@
     }
 
     @Override
-    public boolean isEffective(BundleRequirement br)
+    public boolean isEffective(Requirement br)
     {
         return m_state.isEffective(br);
     }
 
     @Override
-    public Map<BundleRevision, BundleWiring> getWirings()
+    public Map<Resource, Wiring> getWirings()
     {
         return m_wirings;
     }
-
-    public void checkNativeLibraries(BundleRevision rev) throws ResolveException
-    {
-        m_state.checkNativeLibraries(rev);
-    }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index dec5a0c..191a65f 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -42,7 +42,6 @@
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.wiring.BundleCapability;
 
 public class ServiceRegistry
 {
diff --git a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
index 11464a1..3ec6c76 100644
--- a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
@@ -36,14 +36,12 @@
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.CandidateComparator;
 import org.apache.felix.framework.resolver.ResolveException;
-import org.apache.felix.framework.resolver.Resolver;
-import org.apache.felix.framework.resolver.ResolverImpl;
-import org.apache.felix.framework.resolver.ResolverWire;
 import org.apache.felix.framework.util.ShrinkableCollection;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.NativeLibrary;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.apache.felix.framework.wiring.BundleWireImpl;
+import org.apache.felix.resolver.ResolverImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleException;
@@ -60,12 +58,19 @@
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.resource.Requirement;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.resolver.Resolver;
 
 class StatefulResolver
 {
     private final Logger m_logger;
     private final Felix m_felix;
-    private final Resolver m_resolver;
+    private final ServiceRegistry m_registry;
+    private final ResolverImpl m_resolver;
     private boolean m_isResolving = false;
 
     // Set of all revisions.
@@ -83,9 +88,10 @@
     // Parsed framework environments
     private final Set<String> m_fwkExecEnvSet;
 
-    StatefulResolver(Felix felix)
+    StatefulResolver(Felix felix, ServiceRegistry registry)
     {
         m_felix = felix;
+        m_registry = registry;
         m_logger = m_felix.getLogger();
         m_resolver = new ResolverImpl(m_logger);
 
@@ -113,6 +119,14 @@
         m_capSets.put(BundleRevision.HOST_NAMESPACE,  new CapabilitySet(indices, true));
     }
 
+    void start()
+    {
+        m_registry.registerService(m_felix._getBundleContext(),
+                new String[] { Resolver.class.getName() },
+                m_resolver,
+                null);
+    }
+
     synchronized void addRevision(BundleRevision br)
     {
         // Always attempt to remove the revision, since
@@ -165,7 +179,7 @@
         }
     }
 
-    boolean isEffective(BundleRequirement req)
+    boolean isEffective(Requirement req)
     {
         String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
         return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
@@ -212,24 +226,29 @@
             }
 
             // Find the matching candidates.
-            Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
+            Set<Capability> matches = capSet.match(sf, obeyMandatory);
             // Filter matching candidates.
-            for (BundleCapability cap : matches)
+            for (Capability cap : matches)
             {
+                if (!(cap instanceof BundleCapability))
+                    continue;
+
+                BundleCapability bcap = (BundleCapability) cap;
+
                 // Filter according to security.
-                if (invokeHooksAndSecurity && filteredBySecurity((BundleRequirement)req, cap))
+                if (invokeHooksAndSecurity && filteredBySecurity((BundleRequirement)req, bcap))
                 {
                     continue;
                 }
                 // Filter already resolved hosts, since we don't support
                 // dynamic attachment of fragments.
                 if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE)
-                    && (cap.getRevision().getWiring() != null))
+                    && (bcap.getRevision().getWiring() != null))
                 {
                     continue;
                 }
 
-                result.add(cap);
+                result.add(bcap);
             }
         }
 
@@ -341,7 +360,7 @@
     void resolve(
         Set<BundleRevision> mandatory,
         Set<BundleRevision> optional)
-        throws ResolveException, BundleException
+        throws ResolutionException, BundleException
     {
         // Acquire global lock.
         boolean locked = m_felix.acquireGlobalLock();
@@ -360,7 +379,7 @@
         }
         m_isResolving = true;
 
-        Map<BundleRevision, List<ResolverWire>> wireMap = null;
+        Map<Resource, List<Wire>> wireMap = null;
         try
         {
             // Make our own copy of revisions.
@@ -405,7 +424,7 @@
 
             // Catch any resolve exception to rethrow later because
             // we may need to call end() on resolver hooks.
-            ResolveException rethrow = null;
+            ResolutionException rethrow = null;
             try
             {
                 // Resolve the revision.
@@ -418,7 +437,7 @@
                         optional,
                         getFragments()));
             }
-            catch (ResolveException ex)
+            catch (ResolutionException ex)
             {
                 rethrow = ex;
             }
@@ -447,7 +466,7 @@
     }
 
     BundleRevision resolve(BundleRevision revision, String pkgName)
-        throws ResolveException, BundleException
+        throws ResolutionException, BundleException
     {
         BundleRevision provider = null;
 
@@ -475,7 +494,7 @@
             }
             m_isResolving = true;
 
-            Map<BundleRevision, List<ResolverWire>> wireMap = null;
+            Map<Resource, List<Wire>> wireMap = null;
             try
             {
                 // Double check to make sure that someone hasn't beaten us to
@@ -496,20 +515,74 @@
 
                     // Catch any resolve exception to rethrow later because
                     // we may need to call end() on resolver hooks.
-                    ResolveException rethrow = null;
+                    ResolutionException rethrow = null;
                     try
                     {
+                        List<BundleRequirement> dynamics =
+                                Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
+
+                        // Loop through the importer's dynamic requirements to determine if
+                        // there is a matching one for the package from which we want to
+                        // load a class.
+                        Map<String, Object> attrs = Collections.singletonMap(
+                                BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
+                        BundleRequirementImpl req = new BundleRequirementImpl(
+                                revision,
+                                BundleRevision.PACKAGE_NAMESPACE,
+                                Collections.EMPTY_MAP,
+                                attrs);
+                        List<BundleCapability> candidates = findProvidersInternal(record, req, false, true);
+
+                        // Try to find a dynamic requirement that matches the capabilities.
+                        BundleRequirementImpl dynReq = null;
+                        for (int dynIdx = 0;
+                             (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
+                             dynIdx++)
+                        {
+                            for (Iterator<BundleCapability> itCand = candidates.iterator();
+                                 (dynReq == null) && itCand.hasNext(); )
+                            {
+                                Capability cap = itCand.next();
+                                if (CapabilitySet.matches(
+                                        cap,
+                                        ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter()))
+                                {
+                                    dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
+                                }
+                            }
+                        }
+
+                        // If we found a matching dynamic requirement, then filter out
+                        // any candidates that do not match it.
+                        if (dynReq != null)
+                        {
+                            for (Iterator<BundleCapability> itCand = candidates.iterator();
+                                 itCand.hasNext(); )
+                            {
+                                Capability cap = itCand.next();
+                                if (!CapabilitySet.matches(
+                                        cap, dynReq.getFilter()))
+                                {
+                                    itCand.remove();
+                                }
+                            }
+                        }
+                        else
+                        {
+                            candidates.clear();
+                        }
+
                         wireMap = m_resolver.resolve(
                             new ResolveContextImpl(
                                 this,
                                 getWirings(),
                                 record,
-                                Collections.EMPTY_LIST,
-                                Collections.EMPTY_LIST,
+                                Collections.<BundleRevision>emptyList(),
+                                Collections.<BundleRevision>emptyList(),
                                 getFragments()),
-                            revision, pkgName);
+                            revision, dynReq, new ArrayList<Capability>(candidates));
                     }
-                    catch (ResolveException ex)
+                    catch (ResolutionException ex)
                     {
                         rethrow = ex;
                     }
@@ -525,8 +598,8 @@
 
                     if ((wireMap != null) && wireMap.containsKey(revision))
                     {
-                        List<ResolverWire> dynamicWires = wireMap.remove(revision);
-                        ResolverWire dynamicWire = dynamicWires.get(0);
+                        List<Wire> dynamicWires = wireMap.remove(revision);
+                        Wire dynamicWire = dynamicWires.get(0);
 
                         // Mark all revisions as resolved.
                         markResolvedRevisions(wireMap);
@@ -534,22 +607,35 @@
                         // Dynamically add new wire to importing revision.
                         if (dynamicWire != null)
                         {
-                            BundleWire bw = new BundleWireImpl(
-                                dynamicWire.getRequirer(),
-                                dynamicWire.getRequirement(),
-                                dynamicWire.getProvider(),
-                                dynamicWire.getCapability());
+                            // TODO is a rw already a BundleWire?
+                            // TODO can we optimize this?
+                            if (dynamicWire.getRequirer() instanceof BundleRevision &&
+                                dynamicWire.getRequirement() instanceof BundleRequirement &&
+                                dynamicWire.getProvider() instanceof BundleRevision &&
+                                dynamicWire.getCapability() instanceof BundleCapability)
+                            {
+                                BundleRevision dwRequirer = (BundleRevision) dynamicWire.getRequirer();
+                                BundleRequirement dwRequirement = (BundleRequirement) dynamicWire.getRequirement();
+                                BundleRevision dwProvider = (BundleRevision) dynamicWire.getProvider();
+                                BundleCapability dwCapability = (BundleCapability) dynamicWire.getCapability();
 
-                            m_felix.getDependencies().addDependent(bw);
+                                BundleWire bw = new BundleWireImpl(
+                                    dwRequirer,
+                                    dwRequirement,
+                                    dwProvider,
+                                    dwCapability);
 
-                            ((BundleWiringImpl) revision.getWiring()).addDynamicWire(bw);
+                                m_felix.getDependencies().addDependent(bw);
 
-                            m_felix.getLogger().log(
-                                Logger.LOG_DEBUG,
-                                "DYNAMIC WIRE: " + dynamicWire);
+                                ((BundleWiringImpl) revision.getWiring()).addDynamicWire(bw);
 
-                            provider = ((BundleWiringImpl) revision.getWiring())
-                                .getImportedPackageSource(pkgName);
+                                m_felix.getLogger().log(
+                                    Logger.LOG_DEBUG,
+                                    "DYNAMIC WIRE: " + dynamicWire);
+
+                                provider = ((BundleWiringImpl) revision.getWiring())
+                                    .getImportedPackageSource(pkgName);
+                            }
                         }
                     }
                 }
@@ -570,7 +656,7 @@
 
     private ResolverHookRecord prepareResolverHooks(
         Set<BundleRevision> mandatory, Set<BundleRevision> optional)
-        throws BundleException
+        throws BundleException, ResolutionException
     {
         // This map maps the hook factory service to the actual hook objects. It
         // needs to be a map that preserves insertion order to ensure that we call
@@ -829,7 +915,7 @@
             for (Iterator<BundleCapability> itCand = candidates.iterator();
                 (dynReq == null) && itCand.hasNext(); )
             {
-                BundleCapability cap = itCand.next();
+                Capability cap = itCand.next();
                 if (CapabilitySet.matches(
                     cap,
                     ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter()))
@@ -846,7 +932,7 @@
             for (Iterator<BundleCapability> itCand = candidates.iterator();
                 itCand.hasNext(); )
             {
-                BundleCapability cap = itCand.next();
+                Capability cap = itCand.next();
                 if (!CapabilitySet.matches(
                     cap, dynReq.getFilter()))
                 {
@@ -862,7 +948,7 @@
         return !candidates.isEmpty();
     }
 
-    private void markResolvedRevisions(Map<BundleRevision, List<ResolverWire>> wireMap)
+    private void markResolvedRevisions(Map<Resource, List<Wire>> wireMap)
         throws ResolveException
     {
         boolean debugLog = m_felix.getLogger().getLogLevel() >= Logger.LOG_DEBUG;
@@ -878,26 +964,28 @@
         {
             // First pass: Loop through the wire map to find the host wires
             // for any fragments and map a host to all of its fragments.
-            Map<BundleRevision, List<BundleRevision>> hosts =
-                new HashMap<BundleRevision, List<BundleRevision>>();
-            for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+            Map<Resource, List<BundleRevision>> hosts =
+                new HashMap<Resource, List<BundleRevision>>();
+            for (Entry<Resource, List<Wire>> entry : wireMap.entrySet())
             {
-                BundleRevision revision = entry.getKey();
-                List<ResolverWire> wires = entry.getValue();
+                Resource revision = entry.getKey();
+                List<Wire> wires = entry.getValue();
 
                 if (Util.isFragment(revision))
                 {
-                    for (Iterator<ResolverWire> itWires = wires.iterator();
+                    for (Iterator<Wire> itWires = wires.iterator();
                         itWires.hasNext(); )
                     {
-                        ResolverWire w = itWires.next();
+                        Wire w = itWires.next();
                         List<BundleRevision> fragments = hosts.get(w.getProvider());
                         if (fragments == null)
                         {
                             fragments = new ArrayList<BundleRevision>();
                             hosts.put(w.getProvider(), fragments);
                         }
-                        fragments.add(w.getRequirer());
+
+                        if (w.getRequirer() instanceof BundleRevision)
+                            fragments.add((BundleRevision) w.getRequirer());
                     }
                 }
             }
@@ -911,10 +999,14 @@
             // all wirings.
             Map<BundleRevision, BundleWiringImpl> wirings =
                 new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
-            for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+            for (Entry<Resource, List<Wire>> entry : wireMap.entrySet())
             {
-                BundleRevision revision = entry.getKey();
-                List<ResolverWire> resolverWires = entry.getValue();
+                Resource resource = entry.getKey();
+                if (!(resource instanceof BundleRevision))
+                    continue;
+
+                BundleRevision revision = (BundleRevision) resource;
+                List<Wire> resolverWires = entry.getValue();
 
                 List<BundleWire> bundleWires =
                     new ArrayList<BundleWire>(resolverWires.size());
@@ -936,13 +1028,28 @@
                     new HashMap<String, BundleRevision>();
                 Map<String, List<BundleRevision>> requiredPkgs =
                     new HashMap<String, List<BundleRevision>>();
-                for (ResolverWire rw : resolverWires)
+                for (Wire rw : resolverWires)
                 {
+                    // TODO is a rw already a BundleWire?
+                    // TODO can we optimize this?
+                    if (!(rw.getRequirer() instanceof BundleRevision))
+                        continue;
+                    BundleRevision requirer = (BundleRevision) rw.getRequirer();
+                    if (!(rw.getRequirement() instanceof BundleRequirement))
+                        continue;
+                    BundleRequirement requirement = (BundleRequirement) rw.getRequirement();
+                    if (!(rw.getProvider() instanceof BundleRevision))
+                        continue;
+                    BundleRevision provider = (BundleRevision) rw.getProvider();
+                    if (!(rw.getCapability() instanceof BundleCapability))
+                        continue;
+                    BundleCapability capability = (BundleCapability) rw.getCapability();
+
                     BundleWire bw = new BundleWireImpl(
-                        rw.getRequirer(),
-                        rw.getRequirement(),
-                        rw.getProvider(),
-                        rw.getCapability());
+                        requirer,
+                        requirement,
+                        provider,
+                        capability);
                     bundleWires.add(bw);
 
                     if (Util.isFragment(revision))
@@ -961,19 +1068,19 @@
                             m_felix.getLogger().log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
                         }
 
-                        if (rw.getCapability().getNamespace()
+                        if (capability.getNamespace()
                             .equals(BundleRevision.PACKAGE_NAMESPACE))
                         {
                             importedPkgs.put(
-                                (String) rw.getCapability().getAttributes()
+                                (String) capability.getAttributes()
                                     .get(BundleRevision.PACKAGE_NAMESPACE),
-                                rw.getProvider());
+                                provider);
                         }
-                        else if (rw.getCapability().getNamespace()
+                        else if (capability.getNamespace()
                             .equals(BundleRevision.BUNDLE_NAMESPACE))
                         {
                             Set<String> pkgs = calculateExportedAndReexportedPackages(
-                                    rw.getProvider(),
+                                    provider,
                                     wireMap,
                                     new HashSet<String>(),
                                     new HashSet<BundleRevision>());
@@ -985,7 +1092,7 @@
                                     revs = new ArrayList<BundleRevision>();
                                     requiredPkgs.put(pkg, revs);
                                 }
-                                revs.add(rw.getProvider());
+                                revs.add(provider);
                             }
                         }
                     }
@@ -1110,17 +1217,21 @@
         }
     }
 
-    private void fireResolvedEvents(Map<BundleRevision, List<ResolverWire>> wireMap)
+    private void fireResolvedEvents(Map<Resource, List<Wire>> wireMap)
     {
         if (wireMap != null)
         {
-            Iterator<Entry<BundleRevision, List<ResolverWire>>> iter =
+            Iterator<Entry<Resource, List<Wire>>> iter =
                 wireMap.entrySet().iterator();
             // Iterate over the map to fire necessary RESOLVED events.
             while (iter.hasNext())
             {
-                Entry<BundleRevision, List<ResolverWire>> entry = iter.next();
-                BundleRevision revision = entry.getKey();
+                Entry<Resource, List<Wire>> entry = iter.next();
+                Resource resource = entry.getKey();
+                if (!(resource instanceof BundleRevision))
+                    continue;
+
+                BundleRevision revision = (BundleRevision) resource;
 
                 // Fire RESOLVED events for all fragments.
                 List<BundleRevision> fragments =
@@ -1137,7 +1248,7 @@
 
     private static Set<String> calculateExportedAndReexportedPackages(
         BundleRevision br,
-        Map<BundleRevision, List<ResolverWire>> wireMap,
+        Map<Resource, List<Wire>> wireMap,
         Set<String> pkgs,
         Set<BundleRevision> cycles)
     {
@@ -1159,7 +1270,7 @@
             // visibility, since we need to include those packages too.
             if (br.getWiring() == null)
             {
-                for (ResolverWire rw : wireMap.get(br))
+                for (Wire rw : wireMap.get(br))
                 {
                     if (rw.getCapability().getNamespace().equals(
                         BundleRevision.BUNDLE_NAMESPACE))
@@ -1169,7 +1280,8 @@
                         if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
                         {
                             calculateExportedAndReexportedPackages(
-                                rw.getProvider(),
+                                // TODO need to fix the cast
+                                (BundleRevision) rw.getProvider(),
                                 wireMap,
                                 pkgs,
                                 cycles);
@@ -1526,9 +1638,9 @@
         return unresolved;
     }
 
-    private synchronized Map<BundleRevision, BundleWiring> getWirings()
+    private synchronized Map<Resource, Wiring> getWirings()
     {
-        Map<BundleRevision, BundleWiring> wirings = new HashMap<BundleRevision, BundleWiring>();
+        Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
 
         for (BundleRevision revision : m_revisions)
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
index 8f0c605..a64b4ab 100644
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -39,11 +39,12 @@
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.resource.Capability;
 
 public class CapabilitySet
 {
     private final Map<String, Map<Object, Set<BundleCapability>>> m_indices;
-    private final Set<BundleCapability> m_capSet = new HashSet<BundleCapability>();
+    private final Set<Capability> m_capSet = new HashSet<Capability>();
     private final static SecureAction m_secureAction = new SecureAction();
 
     public void dump()
@@ -180,17 +181,17 @@
         }
     }
 
-    public Set<BundleCapability> match(SimpleFilter sf, boolean obeyMandatory)
+    public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
     {
-        Set<BundleCapability> matches = match(m_capSet, sf);
+        Set<Capability> matches = match(m_capSet, sf);
         return (obeyMandatory)
             ? matchMandatory(matches, sf)
             : matches;
     }
 
-    private Set<BundleCapability> match(Set<BundleCapability> caps, SimpleFilter sf)
+    private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
     {
-        Set<BundleCapability> matches = new HashSet<BundleCapability>();
+        Set<Capability> matches = new HashSet<Capability>();
 
         if (sf.getOperation() == SimpleFilter.MATCH_ALL)
         {
@@ -247,9 +248,9 @@
             }
             else
             {
-                for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+                for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
                 {
-                    BundleCapability cap = it.next();
+                    Capability cap = it.next();
                     Object lhs = cap.getAttributes().get(sf.getName());
                     if (lhs != null)
                     {
@@ -265,12 +266,12 @@
         return matches;
     }
 
-    public static boolean matches(BundleCapability cap, SimpleFilter sf)
+    public static boolean matches(Capability cap, SimpleFilter sf)
     {
         return matchesInternal(cap, sf) && matchMandatory(cap, sf);
     }
 
-    private static boolean matchesInternal(BundleCapability cap, SimpleFilter sf)
+    private static boolean matchesInternal(Capability cap, SimpleFilter sf)
     {
         boolean matched = true;
 
@@ -324,12 +325,12 @@
         return matched;
     }
 
-    private static Set<BundleCapability> matchMandatory(
-        Set<BundleCapability> caps, SimpleFilter sf)
+    private static Set<Capability> matchMandatory(
+        Set<Capability> caps, SimpleFilter sf)
     {
-        for (Iterator<BundleCapability> it = caps.iterator(); it.hasNext(); )
+        for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
         {
-            BundleCapability cap = it.next();
+            Capability cap = it.next();
             if (!matchMandatory(cap, sf))
             {
                 it.remove();
@@ -338,7 +339,7 @@
         return caps;
     }
 
-    private static boolean matchMandatory(BundleCapability cap, SimpleFilter sf)
+    private static boolean matchMandatory(Capability cap, SimpleFilter sf)
     {
         Map<String, Object> attrs = cap.getAttributes();
         for (Entry<String, Object> entry : attrs.entrySet())
@@ -468,7 +469,7 @@
                         return false;
                     }
                 case SimpleFilter.APPROX :
-                    return compareApproximate(((Comparable) lhs), rhs);
+                    return compareApproximate(lhs, rhs);
                 case SimpleFilter.SUBSTRING :
                     return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
                 default:
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
index dccd7ca..a6117f1 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
@@ -19,29 +19,42 @@
 package org.apache.felix.framework.resolver;
 
 import java.util.Comparator;
+
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
 
-public class CandidateComparator implements Comparator<BundleCapability>
+public class CandidateComparator implements Comparator<Capability>
 {
-    public int compare(BundleCapability cap1, BundleCapability cap2)
+    public int compare(Capability cap1, Capability cap2)
     {
         // First check resolved state, since resolved capabilities have priority
         // over unresolved ones. Compare in reverse order since we want to sort
         // in descending order.
         int c = 0;
-        if ((cap1.getRevision().getWiring() != null)
-            && (cap2.getRevision().getWiring() == null))
+
+        BundleCapability bcap1 = null;
+        BundleCapability bcap2 = null;
+
+        if (cap1 instanceof BundleCapability &&
+            cap2 instanceof BundleCapability)
         {
-            c = -1;
-        }
-        else if ((cap1.getRevision().getWiring() == null)
-            && (cap2.getRevision().getWiring() != null))
-        {
-            c = 1;
+            bcap1 = (BundleCapability) cap1;
+            bcap2 = (BundleCapability) cap2;
+
+            if ((bcap1.getRevision().getWiring() != null)
+                && (bcap2.getRevision().getWiring() == null))
+            {
+                c = -1;
+            }
+            else if ((bcap1.getRevision().getWiring() == null)
+                && (bcap2.getRevision().getWiring() != null))
+            {
+                c = 1;
+            }
         }
 
         // Compare revision capabilities.
@@ -82,15 +95,15 @@
         }
 
         // Finally, compare bundle identity.
-        if (c == 0)
+        if (c == 0 && bcap1 != null && bcap2 != null)
         {
-            if (cap1.getRevision().getBundle().getBundleId() <
-                cap2.getRevision().getBundle().getBundleId())
+            if (bcap1.getRevision().getBundle().getBundleId() <
+                bcap2.getRevision().getBundle().getBundleId())
             {
                 c = -1;
             }
-            else if (cap1.getRevision().getBundle().getBundleId() >
-                cap2.getRevision().getBundle().getBundleId())
+            else if (bcap1.getRevision().getBundle().getBundleId() >
+                bcap2.getRevision().getBundle().getBundleId())
             {
                 c = 1;
             }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
deleted file mode 100644
index 9f57f95..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ /dev/null
@@ -1,1046 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import org.apache.felix.framework.ResolveContextImpl;
-import org.apache.felix.framework.util.FelixConstants;
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-class Candidates
-{
-    public static final int MANDATORY = 0;
-    public static final int OPTIONAL = 1;
-    public static final int ON_DEMAND = 2;
-
-    private final Set<BundleRevision> m_mandatoryRevisions;
-    // Maps a capability to requirements that match it.
-    private final Map<BundleCapability, Set<BundleRequirement>> m_dependentMap;
-    // Maps a requirement to the capability it matches.
-    private final Map<BundleRequirement, List<BundleCapability>> m_candidateMap;
-    // Maps a bundle revision to its associated wrapped revision; this only happens
-    // when a revision being resolved has fragments to attach to it.
-    private final Map<BundleRevision, WrappedRevision> m_allWrappedHosts;
-    // Map used when populating candidates to hold intermediate and final results.
-    private final Map<BundleRevision, Object> m_populateResultCache;
-
-    // Flag to signal if fragments are present in the candidate map.
-    private boolean m_fragmentsPresent = false;
-
-    /**
-     * Private copy constructor used by the copy() method.
-     * @param dependentMap the capability dependency map.
-     * @param candidateMap the requirement candidate map.
-     * @param hostFragments the fragment map.
-     * @param wrappedHosts the wrapped hosts map.
-    **/
-    private Candidates(
-        Set<BundleRevision> mandatoryRevisions,
-        Map<BundleCapability, Set<BundleRequirement>> dependentMap,
-        Map<BundleRequirement, List<BundleCapability>> candidateMap,
-        Map<BundleRevision, WrappedRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
-        boolean fragmentsPresent)
-    {
-        m_mandatoryRevisions = mandatoryRevisions;
-        m_dependentMap = dependentMap;
-        m_candidateMap = candidateMap;
-        m_allWrappedHosts = wrappedHosts;
-        m_populateResultCache = populateResultCache;
-        m_fragmentsPresent = fragmentsPresent;
-    }
-
-    /**
-     * Constructs an empty Candidates object.
-    **/
-    public Candidates()
-    {
-        m_mandatoryRevisions = new HashSet<BundleRevision>();
-        m_dependentMap = new HashMap<BundleCapability, Set<BundleRequirement>>();
-        m_candidateMap = new HashMap<BundleRequirement, List<BundleCapability>>();
-        m_allWrappedHosts = new HashMap<BundleRevision, WrappedRevision>();
-        m_populateResultCache = new HashMap<BundleRevision, Object>();
-    }
-
-    /**
-     * Populates candidates for the specified revision. How a revision is
-     * resolved depends on its resolution type as follows:
-     * <ul>
-     *   <li><tt>MANDATORY</tt> - must resolve and failure to do so throws
-     *       an exception.</li>
-     *   <li><tt>OPTIONAL</tt> - attempt to resolve, but no exception is thrown
-     *       if the resolve fails.</li>
-     *   <li><tt>ON_DEMAND</tt> - only resolve on demand; this only applies to
-     *       fragments and will only resolve a fragment if its host is already
-     *       selected as a candidate.</li>
-     * </ul>
-     * @param state the resolver state used for populating the candidates.
-     * @param revision the revision whose candidates should be populated.
-     * @param resolution indicates the resolution type.
-     */
-    public final void populate(
-        ResolveContext rc, BundleRevision revision, int resolution)
-    {
-        // Get the current result cache value, to make sure the revision
-        // hasn't already been populated.
-        Object cacheValue = m_populateResultCache.get(revision);
-        // Has been unsuccessfully populated.
-        if (cacheValue instanceof ResolveException)
-        {
-            return;
-        }
-        // Has been successfully populated.
-        else if (cacheValue instanceof Boolean)
-        {
-            return;
-        }
-
-        // We will always attempt to populate fragments, since this is necessary
-        // for ondemand attaching of fragment. However, we'll only attempt to
-        // populate optional non-fragment revisions if they aren't already
-        // resolved.
-        boolean isFragment = Util.isFragment(revision);
-        if (!isFragment && (revision.getWiring() != null))
-        {
-            return;
-        }
-
-        // Always attempt to populate mandatory or optional revisions.
-        // However, for on-demand fragments only populate if their host
-        // is already populated.
-        if ((resolution != ON_DEMAND)
-            || (isFragment && populateFragmentOndemand(rc, revision)))
-        {
-            if (resolution == MANDATORY)
-            {
-                m_mandatoryRevisions.add(revision);
-            }
-            try
-            {
-                // Try to populate candidates for the optional revision.
-                populateRevision(rc, revision);
-            }
-            catch (ResolveException ex)
-            {
-                // Only throw an exception if resolution is mandatory.
-                if (resolution == MANDATORY)
-                {
-                    throw ex;
-                }
-            }
-        }
-    }
-
-    /**
-     * Populates candidates for the specified revision.
-     * @param state the resolver state used for populating the candidates.
-     * @param revision the revision whose candidates should be populated.
-     */
-// TODO: FELIX3 - Modify to not be recursive.
-    private void populateRevision(ResolveContext rc, BundleRevision revision)
-    {
-        // Determine if we've already calculated this revision's candidates.
-        // The result cache will have one of three values:
-        //   1. A resolve exception if we've already attempted to populate the
-        //      revision's candidates but were unsuccessful.
-        //   2. Boolean.TRUE indicating we've already attempted to populate the
-        //      revision's candidates and were successful.
-        //   3. An array containing the cycle count, current map of candidates
-        //      for already processed requirements, and a list of remaining
-        //      requirements whose candidates still need to be calculated.
-        // For case 1, rethrow the exception. For case 2, simply return immediately.
-        // For case 3, this means we have a cycle so we should continue to populate
-        // the candidates where we left off and not record any results globally
-        // until we've popped completely out of the cycle.
-
-        // Keeps track of the number of times we've reentered this method
-        // for the current revision.
-        Integer cycleCount = null;
-
-        // Keeps track of the candidates we've already calculated for the
-        // current revision's requirements.
-        Map<BundleRequirement, List<BundleCapability>> localCandidateMap = null;
-
-        // Keeps track of the current revision's requirements for which we
-        // haven't yet found candidates.
-        List<BundleRequirement> remainingReqs = null;
-
-        // Get the cache value for the current revision.
-        Object cacheValue = m_populateResultCache.get(revision);
-
-        // This is case 1.
-        if (cacheValue instanceof ResolveException)
-        {
-            throw (ResolveException) cacheValue;
-        }
-        // This is case 2.
-        else if (cacheValue instanceof Boolean)
-        {
-            return;
-        }
-        // This is case 3.
-        else if (cacheValue != null)
-        {
-            // Increment and get the cycle count.
-            cycleCount = (Integer)
-                (((Object[]) cacheValue)[0]
-                    = new Integer(((Integer) ((Object[]) cacheValue)[0]).intValue() + 1));
-            // Get the already populated candidates.
-            localCandidateMap = (Map) ((Object[]) cacheValue)[1];
-            // Get the remaining requirements.
-            remainingReqs = (List) ((Object[]) cacheValue)[2];
-        }
-
-        // If there is no cache value for the current revision, then this is
-        // the first time we are attempting to populate its candidates, so
-        // do some one-time checks and initialization.
-        if ((remainingReqs == null) && (localCandidateMap == null))
-        {
-            // Verify that any native libraries match the current platform.
-            ((ResolveContextImpl) rc).checkNativeLibraries(revision);
-
-            // Record cycle count.
-            cycleCount = new Integer(0);
-
-            // Create a local map for populating candidates first, just in case
-            // the revision is not resolvable.
-            localCandidateMap = new HashMap();
-
-            // Create a modifiable list of the revision's requirements.
-            remainingReqs = new ArrayList(revision.getDeclaredRequirements(null));
-
-            // Add these value to the result cache so we know we are
-            // in the middle of populating candidates for the current
-            // revision.
-            m_populateResultCache.put(revision,
-                cacheValue = new Object[] { cycleCount, localCandidateMap, remainingReqs });
-        }
-
-        // If we have requirements remaining, then find candidates for them.
-        while (!remainingReqs.isEmpty())
-        {
-            BundleRequirement req = remainingReqs.remove(0);
-
-            // Ignore non-effective and dynamic requirements.
-            String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-            if (!rc.isEffective(req)
-                || ((resolution != null)
-                    && resolution.equals(FelixConstants.RESOLUTION_DYNAMIC)))
-            {
-                continue;
-            }
-
-            // Process the candidates, removing any candidates that
-            // cannot resolve.
-            List<BundleCapability> candidates = rc.findProviders(req, true);
-            ResolveException rethrow = processCandidates(rc, revision, candidates);
-
-            // First, due to cycles, makes sure we haven't already failed in
-            // a deeper recursion.
-            Object result = m_populateResultCache.get(revision);
-            if (result instanceof ResolveException)
-            {
-                throw (ResolveException) result;
-            }
-            // Next, if are no candidates remaining and the requirement is not
-            // not optional, then record and throw a resolve exception.
-            else if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
-            {
-                String msg = "Unable to resolve " + revision
-                    + ": missing requirement " + req;
-                if (rethrow != null)
-                {
-                    msg = msg + " [caused by: " + rethrow.getMessage() + "]";
-                }
-                rethrow = new ResolveException(msg, revision, req);
-                m_populateResultCache.put(revision, rethrow);
-                throw rethrow;
-            }
-            // Otherwise, if we actually have candidates for the requirement, then
-            // add them to the local candidate map.
-            else if (candidates.size() > 0)
-            {
-                localCandidateMap.put(req, candidates);
-            }
-        }
-
-        // If we are exiting from a cycle then decrement
-        // cycle counter, otherwise record the result.
-        if (cycleCount.intValue() > 0)
-        {
-            ((Object[]) cacheValue)[0] = new Integer(cycleCount.intValue() - 1);
-        }
-        else if (cycleCount.intValue() == 0)
-        {
-            // Record that the revision was successfully populated.
-            m_populateResultCache.put(revision, Boolean.TRUE);
-
-            // Merge local candidate map into global candidate map.
-            if (localCandidateMap.size() > 0)
-            {
-                add(localCandidateMap);
-            }
-        }
-    }
-
-    private boolean populateFragmentOndemand(ResolveContext rc, BundleRevision revision)
-        throws ResolveException
-    {
-        // Create a modifiable list of the revision's requirements.
-        List<BundleRequirement> remainingReqs =
-            new ArrayList(revision.getDeclaredRequirements(null));
-        // Find the host requirement.
-        BundleRequirement hostReq = null;
-        for (Iterator<BundleRequirement> it = remainingReqs.iterator();
-            it.hasNext(); )
-        {
-            BundleRequirement r = it.next();
-            if (r.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-            {
-                hostReq = r;
-                it.remove();
-                break;
-            }
-        }
-        // Get candidates hosts and keep any that have been populated.
-        List<BundleCapability> hosts = rc.findProviders(hostReq, false);
-        for (Iterator<BundleCapability> it = hosts.iterator(); it.hasNext(); )
-        {
-            BundleCapability host = it.next();
-            if (!isPopulated(host.getRevision()))
-            {
-                it.remove();
-            }
-        }
-        // If there aren't any populated hosts, then we can just
-        // return since this fragment isn't needed.
-        if (hosts.isEmpty())
-        {
-            return false;
-        }
-        // If there are populates host candidates, then finish up
-        // some other checks and prepopulate the result cache with
-        // the work we've done so far.
-        // Verify that any native libraries match the current platform.
-        ((ResolveContextImpl) rc).checkNativeLibraries(revision);
-        // Record cycle count, but start at -1 since it will
-        // be incremented again in populate().
-        Integer cycleCount = new Integer(-1);
-        // Create a local map for populating candidates first, just in case
-        // the revision is not resolvable.
-        Map<BundleRequirement, List<BundleCapability>> localCandidateMap =
-            new HashMap<BundleRequirement, List<BundleCapability>>();
-        // Add the discovered host candidates to the local candidate map.
-        localCandidateMap.put(hostReq, hosts);
-        // Add these value to the result cache so we know we are
-        // in the middle of populating candidates for the current
-        // revision.
-        m_populateResultCache.put(revision,
-            new Object[] { cycleCount, localCandidateMap, remainingReqs });
-        return true;
-    }
-
-    public void populateDynamic(
-        ResolveContext rc, BundleRevision revision,
-        BundleRequirement req, List<BundleCapability> candidates)
-    {
-        // Record the revision associated with the dynamic require
-        // as a mandatory revision.
-        m_mandatoryRevisions.add(revision);
-
-        // Add the dynamic imports candidates.
-        add(req, candidates);
-
-        // Process the candidates, removing any candidates that
-        // cannot resolve.
-        ResolveException rethrow = processCandidates(rc, revision, candidates);
-
-        if (candidates.isEmpty())
-        {
-            if (rethrow == null)
-            {
-                rethrow = new ResolveException("Dynamic import failed.", revision, req);
-            }
-            throw rethrow;
-        }
-
-        m_populateResultCache.put(revision, Boolean.TRUE);
-    }
-
-    /**
-     * This method performs common processing on the given set of candidates.
-     * Specifically, it removes any candidates which cannot resolve and it
-     * synthesizes candidates for any candidates coming from any attached
-     * fragments, since fragment capabilities only appear once, but technically
-     * each host represents a unique capability.
-     * @param state the resolver state.
-     * @param revision the revision being resolved.
-     * @param candidates the candidates to process.
-     * @return a resolve exception to be re-thrown, if any, or null.
-     */
-    private ResolveException processCandidates(
-        ResolveContext rc,
-        BundleRevision revision,
-        List<BundleCapability> candidates)
-    {
-        // Get satisfying candidates and populate their candidates if necessary.
-        ResolveException rethrow = null;
-        Set<BundleCapability> fragmentCands = null;
-        for (Iterator<BundleCapability> itCandCap = candidates.iterator();
-            itCandCap.hasNext(); )
-        {
-            BundleCapability candCap = itCandCap.next();
-
-            boolean isFragment = Util.isFragment(candCap.getRevision());
-
-            // If the capability is from a fragment, then record it
-            // because we have to insert associated host capabilities
-            // if the fragment is already attached to any hosts.
-            if (isFragment)
-            {
-                if (fragmentCands == null)
-                {
-                    fragmentCands = new HashSet<BundleCapability>();
-                }
-                fragmentCands.add(candCap);
-            }
-
-            // If the candidate revision is a fragment, then always attempt
-            // to populate candidates for its dependency, since it must be
-            // attached to a host to be used. Otherwise, if the candidate
-            // revision is not already resolved and is not the current version
-            // we are trying to populate, then populate the candidates for
-            // its dependencies as well.
-            // NOTE: Technically, we don't have to check to see if the
-            // candidate revision is equal to the current revision, but this
-            // saves us from recursing and also simplifies exceptions messages
-            // since we effectively chain exception messages for each level
-            // of recursion; thus, any avoided recursion results in fewer
-            // exceptions to chain when an error does occur.
-            if ((isFragment || (candCap.getRevision().getWiring() == null))
-                && !candCap.getRevision().equals(revision))
-            {
-                try
-                {
-                    populateRevision(rc, candCap.getRevision());
-                }
-                catch (ResolveException ex)
-                {
-                    if (rethrow == null)
-                    {
-                        rethrow = ex;
-                    }
-                    // Remove the candidate since we weren't able to
-                    // populate its candidates.
-                    itCandCap.remove();
-                }
-            }
-        }
-
-        // If any of the candidates for the requirement were from a fragment,
-        // then also insert synthesized hosted capabilities for any other host
-        // to which the fragment is attached since they are all effectively
-        // unique capabilities.
-        if (fragmentCands != null)
-        {
-            for (BundleCapability fragCand : fragmentCands)
-            {
-                // Only necessary for resolved fragments.
-                BundleWiring wiring = fragCand.getRevision().getWiring();
-                if (wiring != null)
-                {
-                    // Fragments only have host wire, so each wire represents
-                    // an attached host.
-                    for (BundleWire wire : wiring.getRequiredWires(null))
-                    {
-                        // If the capability is a package, then make sure the
-                        // host actually provides it in its resolved capabilities,
-                        // since it may be a substitutable export.
-                        if (!fragCand.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                            || wire.getProviderWiring().getCapabilities(null).contains(fragCand))
-                        {
-                            // Note that we can just add this as a candidate
-                            // directly, since we know it is already resolved.
-                            // NOTE: We are synthesizing a hosted capability here,
-                            // but we are not using a ShadowList like we do when
-                            // we synthesizing capabilities for unresolved hosts.
-                            // It is not necessary to use the ShadowList here since
-                            // the host is resolved, because in that case we can
-                            // calculate the proper package space by traversing
-                            // the wiring. In the unresolved case, this isn't possible
-                            // so we need to use the ShadowList so we can keep
-                            // a reference to a synthesized resource with attached
-                            // fragments so we can correctly calculate its package
-                            // space.
-                            rc.insertHostedCapability(candidates,
-                                new WrappedCapability(
-                                    wire.getCapability().getRevision(),
-                                    (BundleCapabilityImpl) fragCand));
-                        }
-                    }
-                }
-            }
-        }
-
-        return rethrow;
-    }
-
-    public boolean isPopulated(BundleRevision revision)
-    {
-        Object value = m_populateResultCache.get(revision);
-        return ((value != null) && (value instanceof Boolean));
-    }
-
-    public ResolveException getResolveException(BundleRevision revision)
-    {
-        Object value = m_populateResultCache.get(revision);
-        return ((value != null) && (value instanceof ResolveException))
-            ? (ResolveException) value : null;
-    }
-
-    /**
-     * Adds a requirement and its matching candidates to the internal data
-     * structure. This method assumes it owns the data being passed in and
-     * does not make a copy. It takes the data and processes, such as calculating
-     * which requirements depend on which capabilities and recording any fragments
-     * it finds for future merging.
-     * @param req the requirement to add.
-     * @param candidates the candidates matching the requirement.
-    **/
-    private void add(BundleRequirement req, List<BundleCapability> candidates)
-    {
-        if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-        {
-            m_fragmentsPresent = true;
-        }
-
-        // Record the candidates.
-        m_candidateMap.put(req, candidates);
-    }
-
-    /**
-     * Adds requirements and candidates in bulk. The outer map is not retained
-     * by this method, but the inner data structures are, so they should not
-     * be further modified by the caller.
-     * @param candidates the bulk requirements and candidates to add.
-    **/
-    private void add(Map<BundleRequirement, List<BundleCapability>> candidates)
-    {
-        for (Entry<BundleRequirement, List<BundleCapability>> entry : candidates.entrySet())
-        {
-            add(entry.getKey(), entry.getValue());
-        }
-    }
-
-    /**
-     * Returns the wrapped module associated with the given module. If the module
-     * was not wrapped, then the module itself is returned. This is really only
-     * needed to determine if the root modules of the resolve have been wrapped.
-     * @param m the module whose wrapper is desired.
-     * @return the wrapper module or the module itself if it was not wrapped.
-    **/
-    public BundleRevision getWrappedHost(BundleRevision m)
-    {
-        BundleRevision wrapped = m_allWrappedHosts.get(m);
-        return (wrapped == null) ? m : wrapped;
-    }
-
-    /**
-     * Gets the candidates associated with a given requirement.
-     * @param req the requirement whose candidates are desired.
-     * @return the matching candidates or null.
-    **/
-    public List<BundleCapability> getCandidates(BundleRequirement req)
-    {
-        return m_candidateMap.get(req);
-    }
-
-    /**
-     * Merges fragments into their hosts. It does this by wrapping all host
-     * modules and attaching their selected fragments, removing all unselected
-     * fragment modules, and replacing all occurrences of the original fragments
-     * in the internal data structures with the wrapped host modules instead.
-     * Thus, fragment capabilities and requirements are merged into the appropriate
-     * host and the candidates for the fragment now become candidates for the host.
-     * Likewise, any module depending on a fragment now depend on the host. Note
-     * that this process is sort of like multiplication, since one fragment that
-     * can attach to two hosts effectively gets multiplied across the two hosts.
-     * So, any modules being satisfied by the fragment will end up having the
-     * two hosts as potential candidates, rather than the single fragment.
-     * @param existingSingletons existing resolved singletons.
-     * @throws ResolveException if the removal of any unselected fragments result
-     *         in the root module being unable to resolve.
-    **/
-    public void prepare(ResolveContext rc)
-    {
-        // Maps a host capability to a map containing its potential fragments;
-        // the fragment map maps a fragment symbolic name to a map that maps
-        // a version to a list of fragments requirements matching that symbolic
-        // name and version.
-        Map<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
-            hostFragments = Collections.EMPTY_MAP;
-        if (m_fragmentsPresent)
-        {
-            hostFragments = populateDependents();
-        }
-
-        // This method performs the following steps:
-        // 1. Select the fragments to attach to a given host.
-        // 2. Wrap hosts and attach fragments.
-        // 3. Remove any unselected fragments. This is necessary because
-        //    other revisions may depend on the capabilities of unselected
-        //    fragments, so we need to remove the unselected fragments and
-        //    any revisions that depends on them, which could ultimately cause
-        //    the entire resolve to fail.
-        // 4. Replace all fragments with any host it was merged into
-        //    (effectively multiplying it).
-        //    * This includes setting candidates for attached fragment
-        //      requirements as well as replacing fragment capabilities
-        //      with host's attached fragment capabilities.
-
-        // Steps 1 and 2
-        List<WrappedRevision> hostRevisions = new ArrayList<WrappedRevision>();
-        List<BundleRevision> unselectedFragments = new ArrayList<BundleRevision>();
-        for (Entry<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
-            hostEntry : hostFragments.entrySet())
-        {
-            // Step 1
-            BundleCapability hostCap = hostEntry.getKey();
-            Map<String, Map<Version, List<BundleRequirement>>> fragments
-                = hostEntry.getValue();
-            List<BundleRevision> selectedFragments = new ArrayList<BundleRevision>();
-            for (Entry<String, Map<Version, List<BundleRequirement>>> fragEntry
-                : fragments.entrySet())
-            {
-                boolean isFirst = true;
-                for (Entry<Version, List<BundleRequirement>> versionEntry
-                    : fragEntry.getValue().entrySet())
-                {
-                    for (BundleRequirement hostReq : versionEntry.getValue())
-                    {
-                        // Selecting the first fragment in each entry, which
-                        // is equivalent to selecting the highest version of
-                        // each fragment with a given symbolic name.
-                        if (isFirst)
-                        {
-                            selectedFragments.add(hostReq.getRevision());
-                            isFirst = false;
-                        }
-                        // For any fragment that wasn't selected, remove the
-                        // current host as a potential host for it and remove it
-                        // as a dependent on the host. If there are no more
-                        // potential hosts for the fragment, then mark it as
-                        // unselected for later removal.
-                        else
-                        {
-                            m_dependentMap.get(hostCap).remove(hostReq);
-                            List<BundleCapability> hosts = m_candidateMap.get(hostReq);
-                            hosts.remove(hostCap);
-                            if (hosts.isEmpty())
-                            {
-                                unselectedFragments.add(hostReq.getRevision());
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Step 2
-            WrappedRevision wrappedHost =
-                new WrappedRevision(hostCap.getRevision(), selectedFragments);
-            hostRevisions.add(wrappedHost);
-            m_allWrappedHosts.put(hostCap.getRevision(), wrappedHost);
-        }
-
-        // Step 3
-        for (BundleRevision br : unselectedFragments)
-        {
-            removeRevision(br,
-                new ResolveException(
-                    "Fragment was not selected for attachment.", br, null));
-        }
-
-        // Step 4
-        for (WrappedRevision hostRevision : hostRevisions)
-        {
-            // Replaces capabilities from fragments with the capabilities
-            // from the merged host.
-            for (BundleCapability c : hostRevision.getDeclaredCapabilities(null))
-            {
-                // Don't replace the host capability, since the fragment will
-                // really be attached to the original host, not the wrapper.
-                if (!c.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-                {
-                    BundleCapability origCap = ((HostedCapability) c).getDeclaredCapability();
-                    // Note that you might think we could remove the original cap
-                    // from the dependent map, but you can't since it may come from
-                    // a fragment that is attached to multiple hosts, so each host
-                    // will need to make their own copy.
-                    Set<BundleRequirement> dependents = m_dependentMap.get(origCap);
-                    if (dependents != null)
-                    {
-                        dependents = new HashSet<BundleRequirement>(dependents);
-                        m_dependentMap.put(c, dependents);
-                        for (BundleRequirement r : dependents)
-                        {
-                            // We have synthesized hosted capabilities for all
-                            // fragments that have been attached to hosts by
-                            // wrapping the host bundle and their attached
-                            // fragments. We need to use the ResolveContext to
-                            // determine the proper priority order for hosted
-                            // capabilities since the order may depend on the
-                            // declaring host/fragment combination. However,
-                            // internally we completely wrap the host revision
-                            // and make all capabilities/requirements point back
-                            // to the wrapped host not the declaring host. The
-                            // ResolveContext expects HostedCapabilities to point
-                            // to the declaring revision, so we need two separate
-                            // candidate lists: one for the ResolveContext with
-                            // HostedCapabilities pointing back to the declaring
-                            // host and one for the resolver with HostedCapabilities
-                            // pointing back to the wrapped host. We ask the
-                            // ResolveContext to insert its appropriate HostedCapability
-                            // into its list, then we mirror the insert into a
-                            // shadow list with the resolver's HostedCapability.
-                            // We only need to ask the ResolveContext to find
-                            // the insert position for fragment caps since these
-                            // were synthesized and we don't know their priority.
-                            // However, in the resolver's candidate list we need
-                            // to replace all caps with the wrapped caps, no
-                            // matter if they come from the host or fragment,
-                            // since we are completing replacing the declaring
-                            // host and fragments with the wrapped host.
-                            List<BundleCapability> cands = m_candidateMap.get(r);
-                            if (!(cands instanceof ShadowList))
-                            {
-                                ShadowList<BundleCapability> shadow =
-                                    new ShadowList<BundleCapability>(cands);
-                                m_candidateMap.put(r, shadow);
-                                cands = shadow;
-                            }
-
-                            // If the original capability is from a fragment, then
-                            // ask the ResolveContext to insert it and update the
-                            // shadow copy of the list accordingly.
-                            if (!origCap.getRevision().equals(hostRevision.getHost()))
-                            {
-                                List<BundleCapability> original = ((ShadowList) cands).getOriginal();
-                                int removeIdx = original.indexOf(origCap);
-                                original.remove(removeIdx);
-                                int insertIdx = rc.insertHostedCapability(
-                                    original,
-                                    new SimpleHostedCapability(hostRevision.getHost(), origCap));
-                                cands.remove(removeIdx);
-                                cands.add(insertIdx, c);
-                            }
-                            // If the original capability is from the host, then
-                            // we just need to replace it in the shadow list.
-                            else
-                            {
-                                int idx = cands.indexOf(origCap);
-                                cands.set(idx, c);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // Copy candidates for fragment requirements to the host.
-            for (BundleRequirement r : hostRevision.getDeclaredRequirements(null))
-            {
-                BundleRequirement origReq =
-                    ((WrappedRequirement) r).getOriginalRequirement();
-                List<BundleCapability> cands = m_candidateMap.get(origReq);
-                if (cands != null)
-                {
-                    m_candidateMap.put(r, new ArrayList<BundleCapability>(cands));
-                    for (BundleCapability cand : cands)
-                    {
-                        Set<BundleRequirement> dependents = m_dependentMap.get(cand);
-                        dependents.remove(origReq);
-                        dependents.add(r);
-                    }
-                }
-            }
-        }
-
-        // Lastly, verify that all mandatory revisions are still
-        // populated, since some might have become unresolved after
-        // selecting fragments/singletons.
-        for (BundleRevision br : m_mandatoryRevisions)
-        {
-            if (!isPopulated(br))
-            {
-                throw getResolveException(br);
-            }
-        }
-    }
-
-    // Maps a host capability to a map containing its potential fragments;
-    // the fragment map maps a fragment symbolic name to a map that maps
-    // a version to a list of fragments requirements matching that symbolic
-    // name and version.
-    private Map<BundleCapability,
-        Map<String, Map<Version, List<BundleRequirement>>>> populateDependents()
-    {
-        Map<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
-            hostFragments = new HashMap<BundleCapability,
-                Map<String, Map<Version, List<BundleRequirement>>>>();
-        for (Entry<BundleRequirement, List<BundleCapability>> entry : m_candidateMap.entrySet())
-        {
-            BundleRequirement req = entry.getKey();
-            List<BundleCapability> caps = entry.getValue();
-            for (BundleCapability cap : caps)
-            {
-                // Record the requirement as dependent on the capability.
-                Set<BundleRequirement> dependents = m_dependentMap.get(cap);
-                if (dependents == null)
-                {
-                    dependents = new HashSet<BundleRequirement>();
-                    m_dependentMap.put(cap, dependents);
-                }
-                dependents.add(req);
-
-                // Keep track of hosts and associated fragments.
-                if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-                {
-                    Map<String, Map<Version, List<BundleRequirement>>>
-                        fragments = hostFragments.get(cap);
-                    if (fragments == null)
-                    {
-                        fragments = new HashMap<String, Map<Version, List<BundleRequirement>>>();
-                        hostFragments.put(cap, fragments);
-                    }
-                    Map<Version, List<BundleRequirement>> fragmentVersions =
-                        fragments.get(req.getRevision().getSymbolicName());
-                    if (fragmentVersions == null)
-                    {
-                        fragmentVersions =
-                            new TreeMap<Version, List<BundleRequirement>>(Collections.reverseOrder());
-                        fragments.put(req.getRevision().getSymbolicName(), fragmentVersions);
-                    }
-                    List<BundleRequirement> actual = fragmentVersions.get(req.getRevision().getVersion());
-                    if (actual == null)
-                    {
-                        actual = new ArrayList<BundleRequirement>();
-                        fragmentVersions.put(req.getRevision().getVersion(), actual);
-                    }
-                    actual.add(req);
-                }
-            }
-        }
-
-        return hostFragments;
-    }
-
-    /**
-     * Removes a module from the internal data structures if it wasn't selected
-     * as a fragment or a singleton. This process may cause other modules to
-     * become unresolved if they depended on the module's capabilities and there
-     * is no other candidate.
-     * @param revision the module to remove.
-     * @throws ResolveException if removing the module caused the resolve to fail.
-    **/
-    private void removeRevision(BundleRevision revision, ResolveException ex)
-    {
-        // Add removal reason to result cache.
-        m_populateResultCache.put(revision, ex);
-        // Remove from dependents.
-        Set<BundleRevision> unresolvedRevisions = new HashSet<BundleRevision>();
-        remove(revision, unresolvedRevisions);
-        // Remove dependents that failed as a result of removing revision.
-        while (!unresolvedRevisions.isEmpty())
-        {
-            Iterator<BundleRevision> it = unresolvedRevisions.iterator();
-            revision = it.next();
-            it.remove();
-            remove(revision, unresolvedRevisions);
-        }
-    }
-
-    /**
-     * Removes the specified module from the internal data structures, which
-     * involves removing its requirements and its capabilities. This may cause
-     * other modules to become unresolved as a result.
-     * @param br the module to remove.
-     * @param unresolvedRevisions a list to containing any additional modules that
-     *        that became unresolved as a result of removing this module and will
-     *        also need to be removed.
-     * @throws ResolveException if removing the module caused the resolve to fail.
-    **/
-    private void remove(BundleRevision br, Set<BundleRevision> unresolvedRevisions)
-        throws ResolveException
-    {
-        for (BundleRequirement r : br.getDeclaredRequirements(null))
-        {
-            remove(r);
-        }
-
-        for (BundleCapability c : br.getDeclaredCapabilities(null))
-        {
-            remove(c, unresolvedRevisions);
-        }
-    }
-
-    /**
-     * Removes a requirement from the internal data structures.
-     * @param req the requirement to remove.
-    **/
-    private void remove(BundleRequirement req)
-    {
-        boolean isFragment = req.getNamespace().equals(BundleRevision.HOST_NAMESPACE);
-
-        List<BundleCapability> candidates = m_candidateMap.remove(req);
-        if (candidates != null)
-        {
-            for (BundleCapability cap : candidates)
-            {
-                Set<BundleRequirement> dependents = m_dependentMap.get(cap);
-                if (dependents != null)
-                {
-                    dependents.remove(req);
-                }
-            }
-        }
-    }
-
-    /**
-     * Removes a capability from the internal data structures. This may cause
-     * other modules to become unresolved as a result.
-     * @param c the capability to remove.
-     * @param unresolvedRevisions a list to containing any additional modules that
-     *        that became unresolved as a result of removing this module and will
-     *        also need to be removed.
-     * @throws ResolveException if removing the module caused the resolve to fail.
-    **/
-    private void remove(BundleCapability c, Set<BundleRevision> unresolvedRevisions)
-        throws ResolveException
-    {
-        Set<BundleRequirement> dependents = m_dependentMap.remove(c);
-        if (dependents != null)
-        {
-            for (BundleRequirement r : dependents)
-            {
-                List<BundleCapability> candidates = m_candidateMap.get(r);
-                candidates.remove(c);
-                if (candidates.isEmpty())
-                {
-                    m_candidateMap.remove(r);
-                    if (!((BundleRequirementImpl) r).isOptional())
-                    {
-                        String msg = "Unable to resolve " + r.getRevision()
-                            + ": missing requirement " + r;
-                        m_populateResultCache.put(
-                            r.getRevision(), new ResolveException(msg, r.getRevision(), r));
-                        unresolvedRevisions.add(r.getRevision());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates a copy of the Candidates object. This is used for creating
-     * permutations when package space conflicts are discovered.
-     * @return copy of this Candidates object.
-    **/
-    public Candidates copy()
-    {
-        Map<BundleCapability, Set<BundleRequirement>> dependentMap =
-            new HashMap<BundleCapability, Set<BundleRequirement>>();
-        for (Entry<BundleCapability, Set<BundleRequirement>> entry : m_dependentMap.entrySet())
-        {
-            Set<BundleRequirement> dependents = new HashSet<BundleRequirement>(entry.getValue());
-            dependentMap.put(entry.getKey(), dependents);
-        }
-
-        Map<BundleRequirement, List<BundleCapability>> candidateMap =
-            new HashMap<BundleRequirement, List<BundleCapability>>();
-        for (Entry<BundleRequirement, List<BundleCapability>> entry
-            : m_candidateMap.entrySet())
-        {
-            List<BundleCapability> candidates =
-                new ArrayList<BundleCapability>(entry.getValue());
-            candidateMap.put(entry.getKey(), candidates);
-        }
-
-        return new Candidates(
-            m_mandatoryRevisions, dependentMap, candidateMap,
-            m_allWrappedHosts, m_populateResultCache, m_fragmentsPresent);
-    }
-
-    public void dump()
-    {
-        // Create set of all revisions from requirements.
-        Set<BundleRevision> revisions = new HashSet<BundleRevision>();
-        for (Entry<BundleRequirement, List<BundleCapability>> entry
-            : m_candidateMap.entrySet())
-        {
-            revisions.add(entry.getKey().getRevision());
-        }
-        // Now dump the revisions.
-        System.out.println("=== BEGIN CANDIDATE MAP ===");
-        for (BundleRevision br : revisions)
-        {
-            System.out.println("  " + br
-                 + " (" + ((br.getWiring() != null) ? "RESOLVED)" : "UNRESOLVED)"));
-            List<BundleRequirement> reqs = (br.getWiring() != null)
-                ? br.getWiring().getRequirements(null)
-                : br.getDeclaredRequirements(null);
-            for (BundleRequirement req : reqs)
-            {
-                List<BundleCapability> candidates = m_candidateMap.get(req);
-                if ((candidates != null) && (candidates.size() > 0))
-                {
-                    System.out.println("    " + req + ": " + candidates);
-                }
-            }
-            reqs = (br.getWiring() != null)
-                ? Util.getDynamicRequirements(br.getWiring().getRequirements(null))
-                : Util.getDynamicRequirements(br.getDeclaredRequirements(null));
-            for (BundleRequirement req : reqs)
-            {
-                List<BundleCapability> candidates = m_candidateMap.get(req);
-                if ((candidates != null) && (candidates.size() > 0))
-                {
-                    System.out.println("    " + req + ": " + candidates);
-                }
-            }
-        }
-        System.out.println("=== END CANDIDATE MAP ===");
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
deleted file mode 100644
index fc45301..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.apache.felix.framework.resolver;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-
-public interface HostedCapability extends BundleCapability {
-
-	BundleRevision getRevision();
-
-	BundleCapability getDeclaredCapability();
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java
deleted file mode 100644
index 2af0696..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2011, 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.apache.felix.framework.resolver;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-
-public abstract class ResolveContext
-{
-    public Collection<BundleRevision> getMandatoryRevisions()
-    {
-        return emptyCollection();
-    }
-
-    public Collection<BundleRevision> getOptionalRevisions()
-    {
-        return emptyCollection();
-    }
-
-    private static <T> Collection<T> emptyCollection()
-    {
-        return Collections.EMPTY_LIST;
-    }
-
-    public abstract List<BundleCapability> findProviders(BundleRequirement br, boolean obeyMandatory);
-
-    public abstract int insertHostedCapability(List<BundleCapability> caps, HostedCapability hc);
-
-    public abstract boolean isEffective(BundleRequirement br);
-
-    public abstract Map<BundleRevision, BundleWiring> getWirings();
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
index 360ef3d..9d9a232 100755
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
@@ -20,8 +20,9 @@
 
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.resolver.ResolutionException;
 
-public class ResolveException extends RuntimeException
+public class ResolveException extends ResolutionException
 {
     private final BundleRevision m_revision;
     private final BundleRequirement m_req;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
deleted file mode 100644
index 107e4a7..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-public interface Resolver
-{
-    Map<BundleRevision, List<ResolverWire>> resolve(ResolveContext rc);
-    Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolveContext rc, BundleRevision revision, String pkgName);
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
deleted file mode 100644
index 2512144..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ /dev/null
@@ -1,1811 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import org.apache.felix.framework.BundleWiringImpl;
-import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.ResolveContextImpl;
-import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.util.FelixConstants;
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-
-public class ResolverImpl implements Resolver
-{
-    private final Logger m_logger;
-
-    // Holds candidate permutations based on permutating "uses" chains.
-    // These permutations are given higher priority.
-    private final List<Candidates> m_usesPermutations = new ArrayList<Candidates>();
-    // Holds candidate permutations based on permutating requirement candidates.
-    // These permutations represent backtracking on previous decisions.
-    private final List<Candidates> m_importPermutations = new ArrayList<Candidates>();
-
-    public ResolverImpl(Logger logger)
-    {
-        m_logger = logger;
-    }
-
-    public Map<BundleRevision, List<ResolverWire>> resolve(ResolveContext rc)
-    {
-        Map<BundleRevision, List<ResolverWire>> wireMap =
-            new HashMap<BundleRevision, List<ResolverWire>>();
-        Map<BundleRevision, Packages> revisionPkgMap =
-            new HashMap<BundleRevision, Packages>();
-
-        Collection<BundleRevision> mandatoryRevisions = rc.getMandatoryRevisions();
-        Collection<BundleRevision> optionalRevisions = rc.getOptionalRevisions();
-        Collection<BundleRevision> ondemandFragments = (rc instanceof ResolveContextImpl)
-            ? ((ResolveContextImpl) rc).getOndemandRevisions() : Collections.EMPTY_LIST;
-        boolean retry;
-        do
-        {
-            retry = false;
-
-            try
-            {
-                // Create object to hold all candidates.
-                Candidates allCandidates = new Candidates();
-
-                // Populate mandatory revisions; since these are mandatory
-                // revisions, failure throws a resolve exception.
-                for (Iterator<BundleRevision> it = mandatoryRevisions.iterator();
-                    it.hasNext(); )
-                {
-                    BundleRevision br = it.next();
-                    if (Util.isFragment(br) || (br.getWiring() == null))
-                    {
-                        allCandidates.populate(rc, br, Candidates.MANDATORY);
-                    }
-                    else
-                    {
-                        it.remove();
-                    }
-                }
-
-                // Populate optional revisions; since these are optional
-                // revisions, failure does not throw a resolve exception.
-                for (BundleRevision br : optionalRevisions)
-                {
-                    boolean isFragment = Util.isFragment(br);
-                    if (isFragment || (br.getWiring() == null))
-                    {
-                        allCandidates.populate(rc, br, Candidates.OPTIONAL);
-                    }
-                }
-
-                // Populate ondemand fragments; since these are optional
-                // revisions, failure does not throw a resolve exception.
-                for (BundleRevision br : ondemandFragments)
-                {
-                    boolean isFragment = Util.isFragment(br);
-                    if (isFragment)
-                    {
-                        allCandidates.populate(rc, br, Candidates.ON_DEMAND);
-                    }
-                }
-
-                // Merge any fragments into hosts.
-                allCandidates.prepare(rc);
-
-                // Create a combined list of populated revisions; for
-                // optional revisions. We do not need to consider ondemand
-                // fragments, since they will only be pulled in if their
-                // host is already present.
-                Set<BundleRevision> allRevisions =
-                    new HashSet<BundleRevision>(mandatoryRevisions);
-                for (BundleRevision br : optionalRevisions)
-                {
-                    if (allCandidates.isPopulated(br))
-                    {
-                        allRevisions.add(br);
-                    }
-                }
-
-                // Record the initial candidate permutation.
-                m_usesPermutations.add(allCandidates);
-
-                ResolveException rethrow = null;
-
-                // If a populated revision is a fragment, then its host
-                // must ultimately be verified, so store its host requirement
-                // to use for package space calculation.
-                Map<BundleRevision, List<BundleRequirement>> hostReqs =
-                    new HashMap<BundleRevision, List<BundleRequirement>>();
-                for (BundleRevision br : allRevisions)
-                {
-                    if (Util.isFragment(br))
-                    {
-                        hostReqs.put(
-                            br,
-                            br.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE));
-                    }
-                }
-
-                do
-                {
-                    rethrow = null;
-
-                    revisionPkgMap.clear();
-                    m_packageSourcesCache.clear();
-
-                    allCandidates = (m_usesPermutations.size() > 0)
-                        ? m_usesPermutations.remove(0)
-                        : m_importPermutations.remove(0);
-//allCandidates.dump();
-
-                    for (BundleRevision br : allRevisions)
-                    {
-                        BundleRevision target = br;
-
-                        // If we are resolving a fragment, then get its
-                        // host candidate and verify it instead.
-                        List<BundleRequirement> hostReq = hostReqs.get(br);
-                        if (hostReq != null)
-                        {
-                            target = allCandidates.getCandidates(hostReq.get(0))
-                                .iterator().next().getRevision();
-                        }
-
-                        calculatePackageSpaces(
-                            allCandidates.getWrappedHost(target), allCandidates, revisionPkgMap,
-                            new HashMap(), new HashSet());
-//System.out.println("+++ PACKAGE SPACES START +++");
-//dumpRevisionPkgMap(revisionPkgMap);
-//System.out.println("+++ PACKAGE SPACES END +++");
-
-                        try
-                        {
-                            checkPackageSpaceConsistency(
-                                rc, false, allCandidates.getWrappedHost(target),
-                                allCandidates, revisionPkgMap, new HashMap());
-                        }
-                        catch (ResolveException ex)
-                        {
-                            rethrow = ex;
-                        }
-                    }
-                }
-                while ((rethrow != null)
-                    && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
-
-                // If there is a resolve exception, then determine if an
-                // optionally resolved revision is to blame (typically a fragment).
-                // If so, then remove the optionally resolved resolved and try
-                // again; otherwise, rethrow the resolve exception.
-                if (rethrow != null)
-                {
-                    BundleRevision faultyRevision =
-                        getDeclaringBundleRevision(rethrow.getRevision());
-                    if (rethrow.getRequirement() instanceof WrappedRequirement)
-                    {
-                        faultyRevision =
-                            ((WrappedRequirement) rethrow.getRequirement())
-                                .getOriginalRequirement().getRevision();
-                    }
-                    if (optionalRevisions.remove(faultyRevision))
-                    {
-                        retry = true;
-                    }
-                    else if (ondemandFragments.remove(faultyRevision))
-                    {
-                        retry = true;
-                    }
-                    else
-                    {
-                        throw rethrow;
-                    }
-                }
-                // If there is no exception to rethrow, then this was a clean
-                // resolve, so populate the wire map.
-                else
-                {
-                    for (BundleRevision br : allRevisions)
-                    {
-                        BundleRevision target = br;
-
-                        // If we are resolving a fragment, then we
-                        // actually want to populate its host's wires.
-                        List<BundleRequirement> hostReq = hostReqs.get(br);
-                        if (hostReq != null)
-                        {
-                            target = allCandidates.getCandidates(hostReq.get(0))
-                                .iterator().next().getRevision();
-                        }
-
-                        if (allCandidates.isPopulated(target))
-                        {
-                            wireMap =
-                                populateWireMap(
-                                    allCandidates.getWrappedHost(target),
-                                    revisionPkgMap, wireMap, allCandidates);
-                        }
-                    }
-                }
-            }
-            finally
-            {
-                // Always clear the state.
-                m_usesPermutations.clear();
-                m_importPermutations.clear();
-            }
-        }
-        while (retry);
-
-        return wireMap;
-    }
-
-    public Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolveContext rc, BundleRevision revision, String pkgName)
-    {
-        // We can only create a dynamic import if the following
-        // conditions are met:
-        // 1. The specified revision is resolved.
-        // 2. The package in question is not already imported.
-        // 3. The package in question is not accessible via require-bundle.
-        // 4. The package in question is not exported by the revision.
-        // 5. The package in question matches a dynamic import of the revision.
-        // The following call checks all of these conditions and returns
-        // the associated dynamic import and matching capabilities.
-        Candidates allCandidates =
-            getDynamicImportCandidates(rc, revision, pkgName);
-        if (allCandidates != null)
-        {
-            Collection<BundleRevision> ondemandFragments = (rc instanceof ResolveContextImpl)
-                ? ((ResolveContextImpl) rc).getOndemandRevisions() : Collections.EMPTY_LIST;
-
-            Map<BundleRevision, List<ResolverWire>> wireMap =
-                new HashMap<BundleRevision, List<ResolverWire>>();
-            Map<BundleRevision, Packages> revisionPkgMap =
-                new HashMap<BundleRevision, Packages>();
-
-            boolean retry;
-            do
-            {
-                retry = false;
-
-                try
-                {
-                    // Try to populate optional fragments.
-                    for (BundleRevision br : ondemandFragments)
-                    {
-                        if (Util.isFragment(br))
-                        {
-                            allCandidates.populate(rc, br, Candidates.ON_DEMAND);
-                        }
-                    }
-
-                    // Merge any fragments into hosts.
-                    allCandidates.prepare(rc);
-
-                    // Record the initial candidate permutation.
-                    m_usesPermutations.add(allCandidates);
-
-                    ResolveException rethrow = null;
-
-                    do
-                    {
-                        rethrow = null;
-
-                        revisionPkgMap.clear();
-                        m_packageSourcesCache.clear();
-
-                        allCandidates = (m_usesPermutations.size() > 0)
-                            ? m_usesPermutations.remove(0)
-                            : m_importPermutations.remove(0);
-//allCandidates.dump();
-
-                        // For a dynamic import, the instigating revision
-                        // will never be a fragment since fragments never
-                        // execute code, so we don't need to check for
-                        // this case like we do for a normal resolve.
-
-                        calculatePackageSpaces(
-                            allCandidates.getWrappedHost(revision), allCandidates, revisionPkgMap,
-                            new HashMap(), new HashSet());
-//System.out.println("+++ PACKAGE SPACES START +++");
-//dumpRevisionPkgMap(revisionPkgMap);
-//System.out.println("+++ PACKAGE SPACES END +++");
-
-                        try
-                        {
-                            checkPackageSpaceConsistency(
-                                rc, false, allCandidates.getWrappedHost(revision),
-                                allCandidates, revisionPkgMap, new HashMap());
-                        }
-                        catch (ResolveException ex)
-                        {
-                            rethrow = ex;
-                        }
-                    }
-                    while ((rethrow != null)
-                        && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
-
-                    // If there is a resolve exception, then determine if an
-                    // optionally resolved revision is to blame (typically a fragment).
-                    // If so, then remove the optionally resolved revision and try
-                    // again; otherwise, rethrow the resolve exception.
-                    if (rethrow != null)
-                    {
-                        BundleRevision faultyRevision =
-                            getDeclaringBundleRevision(rethrow.getRevision());
-                        if (rethrow.getRequirement() instanceof WrappedRequirement)
-                        {
-                            faultyRevision =
-                                ((WrappedRequirement) rethrow.getRequirement())
-                                    .getOriginalRequirement().getRevision();
-                        }
-                        if (ondemandFragments.remove(faultyRevision))
-                        {
-                            retry = true;
-                        }
-                        else
-                        {
-                            throw rethrow;
-                        }
-                    }
-                    // If there is no exception to rethrow, then this was a clean
-                    // resolve, so populate the wire map.
-                    else
-                    {
-                        wireMap = populateDynamicWireMap(
-                            revision, pkgName, revisionPkgMap, wireMap, allCandidates);
-                        return wireMap;
-                    }
-                }
-                finally
-                {
-                    // Always clear the state.
-                    m_usesPermutations.clear();
-                    m_importPermutations.clear();
-                }
-            }
-            while (retry);
-        }
-
-        return null;
-    }
-
-    private static Candidates getDynamicImportCandidates(
-        ResolveContext rc, BundleRevision revision, String pkgName)
-    {
-        // Unresolved revisions cannot dynamically import, nor can the default
-        // package be dynamically imported.
-        if ((revision.getWiring() == null) || pkgName.length() == 0)
-        {
-            return null;
-        }
-
-        // If the revision doesn't have dynamic imports, then just return
-        // immediately.
-        List<BundleRequirement> dynamics =
-            Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
-        if ((dynamics == null) || dynamics.isEmpty())
-        {
-            return null;
-        }
-
-        // If the revision exports this package, then we cannot
-        // attempt to dynamically import it.
-        for (BundleCapability cap : revision.getWiring().getCapabilities(null))
-        {
-            if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                && cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName))
-            {
-                return null;
-            }
-        }
-
-        // If this revision already imports or requires this package, then
-        // we cannot dynamically import it.
-        if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
-        {
-            return null;
-        }
-
-        // Determine if any providers of the package exist.
-        Map<String, Object> attrs = Collections.singletonMap(
-            BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
-        BundleRequirementImpl req = new BundleRequirementImpl(
-            revision,
-            BundleRevision.PACKAGE_NAMESPACE,
-            Collections.EMPTY_MAP,
-            attrs);
-        List<BundleCapability> candidates = rc.findProviders(req, false);
-
-        // Try to find a dynamic requirement that matches the capabilities.
-        BundleRequirementImpl dynReq = null;
-        for (int dynIdx = 0;
-            (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
-            dynIdx++)
-        {
-            for (Iterator<BundleCapability> itCand = candidates.iterator();
-                (dynReq == null) && itCand.hasNext(); )
-            {
-                BundleCapability cap = itCand.next();
-                if (CapabilitySet.matches(
-                    (BundleCapabilityImpl) cap,
-                    ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter()))
-                {
-                    dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
-                }
-            }
-        }
-
-        // If we found a matching dynamic requirement, then filter out
-        // any candidates that do not match it.
-        if (dynReq != null)
-        {
-            for (Iterator<BundleCapability> itCand = candidates.iterator();
-                itCand.hasNext(); )
-            {
-                BundleCapability cap = itCand.next();
-                if (!CapabilitySet.matches(
-                    (BundleCapabilityImpl) cap, dynReq.getFilter()))
-                {
-                    itCand.remove();
-                }
-            }
-        }
-        else
-        {
-            candidates.clear();
-        }
-
-        Candidates allCandidates = null;
-
-        if (candidates.size() > 0)
-        {
-            allCandidates = new Candidates();
-            allCandidates.populateDynamic(rc, revision, dynReq, candidates);
-        }
-
-        return allCandidates;
-    }
-
-    private void calculatePackageSpaces(
-        BundleRevision revision,
-        Candidates allCandidates,
-        Map<BundleRevision, Packages> revisionPkgMap,
-        Map<BundleCapability, List<BundleRevision>> usesCycleMap,
-        Set<BundleRevision> cycle)
-    {
-        if (cycle.contains(revision))
-        {
-            return;
-        }
-        cycle.add(revision);
-
-        // Make sure package space hasn't already been calculated.
-        Packages revisionPkgs = revisionPkgMap.get(revision);
-        if (revisionPkgs != null)
-        {
-            if (revisionPkgs.m_isCalculated)
-            {
-                return;
-            }
-            else
-            {
-                revisionPkgs.m_isCalculated = true;
-            }
-        }
-
-        // Create parallel arrays for requirement and proposed candidate
-        // capability or actual capability if revision is resolved or not.
-        List<BundleRequirement> reqs = new ArrayList();
-        List<BundleCapability> caps = new ArrayList();
-        boolean isDynamicImporting = false;
-        if (revision.getWiring() != null)
-        {
-            // Use wires to get actual requirements and satisfying capabilities.
-            for (BundleWire wire : revision.getWiring().getRequiredWires(null))
-            {
-                // Wrap the requirement as a hosted requirement if it comes
-                // from a fragment, since we will need to know the host. We
-                // also need to wrap if the requirement is a dynamic import,
-                // since that requirement will be shared with any other
-                // matching dynamic imports.
-                BundleRequirement r = wire.getRequirement();
-                if (!r.getRevision().equals(wire.getRequirerWiring().getRevision())
-                    || ((r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE) != null)
-                        && r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE).equals("dynamic")))
-                {
-                    r = new WrappedRequirement(
-                        wire.getRequirerWiring().getRevision(),
-                        (BundleRequirementImpl) r);
-                }
-                // Wrap the capability as a hosted capability if it comes
-                // from a fragment, since we will need to know the host.
-                BundleCapability c = wire.getCapability();
-                if (!c.getRevision().equals(wire.getProviderWiring().getRevision()))
-                {
-                    c = new WrappedCapability(
-                        wire.getProviderWiring().getRevision(),
-                        (BundleCapabilityImpl) c);
-                }
-                reqs.add(r);
-                caps.add(c);
-            }
-
-            // Since the revision is resolved, it could be dynamically importing,
-            // so check to see if there are candidates for any of its dynamic
-            // imports.
-            for (BundleRequirement req
-                : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
-            {
-                // Get the candidates for the current requirement.
-                List<BundleCapability> candCaps = allCandidates.getCandidates(req);
-                // Optional requirements may not have any candidates.
-                if (candCaps == null)
-                {
-                    continue;
-                }
-
-                // Grab first (i.e., highest priority) candidate.
-                BundleCapability cap = candCaps.get(0);
-                reqs.add(req);
-                caps.add(cap);
-                isDynamicImporting = true;
-                // Can only dynamically import one at a time, so break
-                // out of the loop after the first.
-                break;
-            }
-        }
-        else
-        {
-            for (BundleRequirement req : revision.getDeclaredRequirements(null))
-            {
-                String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-                if ((resolution == null)
-                    || !resolution.equals(FelixConstants.RESOLUTION_DYNAMIC))
-                {
-                    // Get the candidates for the current requirement.
-                    List<BundleCapability> candCaps = allCandidates.getCandidates(req);
-                    // Optional requirements may not have any candidates.
-                    if (candCaps == null)
-                    {
-                        continue;
-                    }
-
-                    // Grab first (i.e., highest priority) candidate.
-                    BundleCapability cap = candCaps.get(0);
-                    reqs.add(req);
-                    caps.add(cap);
-                }
-            }
-        }
-
-        // First, add all exported packages to the target revision's package space.
-        calculateExportedPackages(revision, allCandidates, revisionPkgMap);
-        revisionPkgs = revisionPkgMap.get(revision);
-
-        // Second, add all imported packages to the target revision's package space.
-        for (int i = 0; i < reqs.size(); i++)
-        {
-            BundleRequirement req = reqs.get(i);
-            BundleCapability cap = caps.get(i);
-            calculateExportedPackages(cap.getRevision(), allCandidates, revisionPkgMap);
-            mergeCandidatePackages(
-                revision, req, cap, revisionPkgMap, allCandidates,
-                new HashMap<BundleRevision, List<BundleCapability>>());
-        }
-
-        // Third, have all candidates to calculate their package spaces.
-        for (int i = 0; i < caps.size(); i++)
-        {
-            calculatePackageSpaces(
-                caps.get(i).getRevision(), allCandidates, revisionPkgMap,
-                usesCycleMap, cycle);
-        }
-
-        // Fourth, if the target revision is unresolved or is dynamically importing,
-        // then add all the uses constraints implied by its imported and required
-        // packages to its package space.
-        // NOTE: We do not need to do this for resolved revisions because their
-        // package space is consistent by definition and these uses constraints
-        // are only needed to verify the consistency of a resolving revision. The
-        // only exception is if a resolved revision is dynamically importing, then
-        // we need to calculate its uses constraints again to make sure the new
-        // import is consistent with the existing package space.
-        if ((revision.getWiring() == null) || isDynamicImporting)
-        {
-            // Merge uses constraints from required capabilities.
-            for (int i = 0; i < reqs.size(); i++)
-            {
-                BundleRequirement req = reqs.get(i);
-                BundleCapability cap = caps.get(i);
-                // Ignore bundle/package requirements, since they are
-                // considered below.
-                if (!req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)
-                    && !req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    List<BundleRequirement> blameReqs = new ArrayList();
-                    blameReqs.add(req);
-
-                    mergeUses(
-                        revision,
-                        revisionPkgs,
-                        cap,
-                        blameReqs,
-                        revisionPkgMap,
-                        allCandidates,
-                        usesCycleMap);
-                }
-            }
-            // Merge uses constraints from imported packages.
-            for (Entry<String, List<Blame>> entry : revisionPkgs.m_importedPkgs.entrySet())
-            {
-                for (Blame blame : entry.getValue())
-                {
-                    // Ignore revisions that import from themselves.
-                    if (!blame.m_cap.getRevision().equals(revision))
-                    {
-                        List<BundleRequirement> blameReqs = new ArrayList();
-                        blameReqs.add(blame.m_reqs.get(0));
-
-                        mergeUses(
-                            revision,
-                            revisionPkgs,
-                            blame.m_cap,
-                            blameReqs,
-                            revisionPkgMap,
-                            allCandidates,
-                            usesCycleMap);
-                    }
-                }
-            }
-            // Merge uses constraints from required bundles.
-            for (Entry<String, List<Blame>> entry : revisionPkgs.m_requiredPkgs.entrySet())
-            {
-                for (Blame blame : entry.getValue())
-                {
-                    List<BundleRequirement> blameReqs = new ArrayList();
-                    blameReqs.add(blame.m_reqs.get(0));
-
-                    mergeUses(
-                        revision,
-                        revisionPkgs,
-                        blame.m_cap,
-                        blameReqs,
-                        revisionPkgMap,
-                        allCandidates,
-                        usesCycleMap);
-                }
-            }
-        }
-    }
-
-    private void mergeCandidatePackages(
-        BundleRevision current, BundleRequirement currentReq, BundleCapability candCap,
-        Map<BundleRevision, Packages> revisionPkgMap,
-        Candidates allCandidates, Map<BundleRevision, List<BundleCapability>> cycles)
-    {
-        List<BundleCapability> cycleCaps = cycles.get(current);
-        if (cycleCaps == null)
-        {
-            cycleCaps = new ArrayList<BundleCapability>();
-            cycles.put(current, cycleCaps);
-        }
-        if (cycleCaps.contains(candCap))
-        {
-            return;
-        }
-        cycleCaps.add(candCap);
-
-        if (candCap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            mergeCandidatePackage(
-                current, false, currentReq, candCap, revisionPkgMap);
-        }
-        else if (candCap.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
-        {
-// TODO: FELIX3 - THIS NEXT LINE IS A HACK. IMPROVE HOW/WHEN WE CALCULATE EXPORTS.
-            calculateExportedPackages(
-                candCap.getRevision(), allCandidates, revisionPkgMap);
-
-            // Get the candidate's package space to determine which packages
-            // will be visible to the current revision.
-            Packages candPkgs = revisionPkgMap.get(candCap.getRevision());
-
-            // We have to merge all exported packages from the candidate,
-            // since the current revision requires it.
-            for (Entry<String, Blame> entry : candPkgs.m_exportedPkgs.entrySet())
-            {
-                mergeCandidatePackage(
-                    current,
-                    true,
-                    currentReq,
-                    entry.getValue().m_cap,
-                    revisionPkgMap);
-            }
-
-            // If the candidate requires any other bundles with reexport visibility,
-            // then we also need to merge their packages too.
-            if (candCap.getRevision().getWiring() != null)
-            {
-                for (BundleWire bw
-                    : candCap.getRevision().getWiring().getRequiredWires(null))
-                {
-                    if (bw.getRequirement().getNamespace()
-                        .equals(BundleRevision.BUNDLE_NAMESPACE))
-                    {
-                        String value = bw.getRequirement()
-                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                        if ((value != null)
-                            && value.equals(Constants.VISIBILITY_REEXPORT))
-                        {
-                            mergeCandidatePackages(
-                                current,
-                                currentReq,
-                                bw.getCapability(),
-                                revisionPkgMap,
-                                allCandidates,
-                                cycles);
-                        }
-                    }
-                }
-            }
-            else
-            {
-                for (BundleRequirement req
-                    : candCap.getRevision().getDeclaredRequirements(null))
-                {
-                    if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
-                    {
-                        String value =
-                            req.getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                        if ((value != null)
-                            && value.equals(Constants.VISIBILITY_REEXPORT)
-                            && (allCandidates.getCandidates(req) != null))
-                        {
-                            mergeCandidatePackages(
-                                current,
-                                currentReq,
-                                allCandidates.getCandidates(req).iterator().next(),
-                                revisionPkgMap,
-                                allCandidates,
-                                cycles);
-                        }
-                    }
-                }
-            }
-        }
-
-        cycles.remove(current);
-    }
-
-    private void mergeCandidatePackage(
-        BundleRevision current, boolean requires,
-        BundleRequirement currentReq, BundleCapability candCap,
-        Map<BundleRevision, Packages> revisionPkgMap)
-    {
-        if (candCap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            // Merge the candidate capability into the revision's package space
-            // for imported or required packages, appropriately.
-
-            String pkgName = (String)
-                candCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
-
-            List blameReqs = new ArrayList();
-            blameReqs.add(currentReq);
-
-            Packages currentPkgs = revisionPkgMap.get(current);
-
-            Map<String, List<Blame>> packages = (requires)
-                ? currentPkgs.m_requiredPkgs
-                : currentPkgs.m_importedPkgs;
-            List<Blame> blames = packages.get(pkgName);
-            if (blames == null)
-            {
-                blames = new ArrayList<Blame>();
-                packages.put(pkgName, blames);
-            }
-            blames.add(new Blame(candCap, blameReqs));
-
-//dumpRevisionPkgs(current, currentPkgs);
-        }
-    }
-
-    private void mergeUses(
-        BundleRevision current, Packages currentPkgs,
-        BundleCapability mergeCap, List<BundleRequirement> blameReqs,
-        Map<BundleRevision, Packages> revisionPkgMap,
-        Candidates allCandidates,
-        Map<BundleCapability, List<BundleRevision>> cycleMap)
-    {
-        // If there are no uses, then just return.
-        // If the candidate revision is the same as the current revision,
-        // then we don't need to verify and merge the uses constraints
-        // since this will happen as we build up the package space.
-        if (current.equals(mergeCap.getRevision()))
-        {
-            return;
-        }
-
-        // Check for cycles.
-        List<BundleRevision> list = cycleMap.get(mergeCap);
-        if ((list != null) && list.contains(current))
-        {
-            return;
-        }
-        list = (list == null) ? new ArrayList<BundleRevision>() : list;
-        list.add(current);
-        cycleMap.put(mergeCap, list);
-
-        for (BundleCapability candSourceCap : getPackageSources(mergeCap, revisionPkgMap))
-        {
-            for (String usedPkgName : ((BundleCapabilityImpl) candSourceCap).getUses())
-            {
-                Packages candSourcePkgs = revisionPkgMap.get(candSourceCap.getRevision());
-                List<Blame> candSourceBlames = null;
-                // Check to see if the used package is exported.
-                Blame candExportedBlame = candSourcePkgs.m_exportedPkgs.get(usedPkgName);
-                if (candExportedBlame != null)
-                {
-                    candSourceBlames = new ArrayList(1);
-                    candSourceBlames.add(candExportedBlame);
-                }
-                else
-                {
-                    // If the used package is not exported, check to see if it
-                    // is required.
-                    candSourceBlames = candSourcePkgs.m_requiredPkgs.get(usedPkgName);
-                    // Lastly, if the used package is not required, check to see if it
-                    // is imported.
-                    candSourceBlames = (candSourceBlames != null)
-                        ? candSourceBlames : candSourcePkgs.m_importedPkgs.get(usedPkgName);
-                }
-
-                // If the used package cannot be found, then just ignore it
-                // since it has no impact.
-                if (candSourceBlames == null)
-                {
-                    continue;
-                }
-
-                List<Blame> usedCaps = currentPkgs.m_usedPkgs.get(usedPkgName);
-                if (usedCaps == null)
-                {
-                    usedCaps = new ArrayList<Blame>();
-                    currentPkgs.m_usedPkgs.put(usedPkgName, usedCaps);
-                }
-                for (Blame blame : candSourceBlames)
-                {
-                    if (blame.m_reqs != null)
-                    {
-                        List<BundleRequirement> blameReqs2 = new ArrayList(blameReqs);
-                        blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
-                        usedCaps.add(new Blame(blame.m_cap, blameReqs2));
-                        mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
-                            revisionPkgMap, allCandidates, cycleMap);
-                    }
-                    else
-                    {
-                        usedCaps.add(new Blame(blame.m_cap, blameReqs));
-                        mergeUses(current, currentPkgs, blame.m_cap, blameReqs,
-                            revisionPkgMap, allCandidates, cycleMap);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkPackageSpaceConsistency(
-        ResolveContext rc,
-        boolean isDynamicImporting,
-        BundleRevision revision,
-        Candidates allCandidates,
-        Map<BundleRevision, Packages> revisionPkgMap,
-        Map<BundleRevision, Object> resultCache)
-    {
-        if ((revision.getWiring() != null) && !isDynamicImporting)
-        {
-            return;
-        }
-        else if(resultCache.containsKey(revision))
-        {
-            return;
-        }
-
-        Packages pkgs = revisionPkgMap.get(revision);
-
-        ResolveException rethrow = null;
-        Candidates permutation = null;
-        Set<BundleRequirement> mutated = null;
-
-        // Check for conflicting imports from fragments.
-        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
-        {
-            if (entry.getValue().size() > 1)
-            {
-                Blame sourceBlame = null;
-                for (Blame blame : entry.getValue())
-                {
-                    if (sourceBlame == null)
-                    {
-                        sourceBlame = blame;
-                    }
-                    else if (!sourceBlame.m_cap.getRevision().equals(blame.m_cap.getRevision()))
-                    {
-                        // Try to permutate the conflicting requirement.
-                        permutate(allCandidates, blame.m_reqs.get(0), m_importPermutations);
-                        // Try to permutate the source requirement.
-                        permutate(allCandidates, sourceBlame.m_reqs.get(0), m_importPermutations);
-                        // Report conflict.
-                        ResolveException ex = new ResolveException(
-                            "Uses constraint violation. Unable to resolve bundle revision "
-                            + revision.getSymbolicName()
-                            + " [" + revision
-                            + "] because it is exposed to package '"
-                            + entry.getKey()
-                            + "' from bundle revisions "
-                            + sourceBlame.m_cap.getRevision().getSymbolicName()
-                            + " [" + sourceBlame.m_cap.getRevision()
-                            + "] and "
-                            + blame.m_cap.getRevision().getSymbolicName()
-                            + " [" + blame.m_cap.getRevision()
-                            + "] via two dependency chains.\n\nChain 1:\n"
-                            + toStringBlame(rc, allCandidates, sourceBlame)
-                            + "\n\nChain 2:\n"
-                            + toStringBlame(rc, allCandidates, blame),
-                            revision,
-                            blame.m_reqs.get(0));
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "Candidate permutation failed due to a conflict with a "
-                            + "fragment import; will try another if possible.",
-                            ex);
-                        throw ex;
-                    }
-                }
-            }
-        }
-
-        // Check if there are any uses conflicts with exported packages.
-        for (Entry<String, Blame> entry : pkgs.m_exportedPkgs.entrySet())
-        {
-            String pkgName = entry.getKey();
-            Blame exportBlame = entry.getValue();
-            if (!pkgs.m_usedPkgs.containsKey(pkgName))
-            {
-                continue;
-            }
-            for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
-            {
-                if (!isCompatible(exportBlame.m_cap, usedBlame.m_cap, revisionPkgMap))
-                {
-                    // Create a candidate permutation that eliminates all candidates
-                    // that conflict with existing selected candidates.
-                    permutation = (permutation != null)
-                        ? permutation
-                        : allCandidates.copy();
-                    rethrow = (rethrow != null)
-                        ? rethrow
-                        : new ResolveException(
-                            "Uses constraint violation. Unable to resolve bundle revision "
-                            + revision.getSymbolicName()
-                            + " [" + revision
-                            + "] because it exports package '"
-                            + pkgName
-                            + "' and is also exposed to it from bundle revision "
-                            + usedBlame.m_cap.getRevision().getSymbolicName()
-                            + " [" + usedBlame.m_cap.getRevision()
-                            + "] via the following dependency chain:\n\n"
-                            + toStringBlame(rc, allCandidates, usedBlame),
-                            null,
-                            null);
-
-                    mutated = (mutated != null)
-                        ? mutated
-                        : new HashSet<BundleRequirement>();
-
-                    for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
-                    {
-                        BundleRequirement req = usedBlame.m_reqs.get(reqIdx);
-
-                        // If we've already permutated this requirement in another
-                        // uses constraint, don't permutate it again just continue
-                        // with the next uses constraint.
-                        if (mutated.contains(req))
-                        {
-                            break;
-                        }
-
-                        // See if we can permutate the candidates for blamed
-                        // requirement; there may be no candidates if the revision
-                        // associated with the requirement is already resolved.
-                        List<BundleCapability> candidates = permutation.getCandidates(req);
-                        if ((candidates != null) && (candidates.size() > 1))
-                        {
-                            mutated.add(req);
-                            // Remove the conflicting candidate.
-                            candidates.remove(0);
-                            // Continue with the next uses constraint.
-                            break;
-                        }
-                    }
-                }
-            }
-
-            if (rethrow != null)
-            {
-                if (mutated.size() > 0)
-                {
-                    m_usesPermutations.add(permutation);
-                }
-                m_logger.log(
-                    Logger.LOG_DEBUG,
-                    "Candidate permutation failed due to a conflict between "
-                    + "an export and import; will try another if possible.",
-                    rethrow);
-                throw rethrow;
-            }
-        }
-
-        // Check if there are any uses conflicts with imported packages.
-        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
-        {
-            for (Blame importBlame : entry.getValue())
-            {
-                String pkgName = entry.getKey();
-                if (!pkgs.m_usedPkgs.containsKey(pkgName))
-                {
-                    continue;
-                }
-                for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
-                {
-                    if (!isCompatible(importBlame.m_cap, usedBlame.m_cap, revisionPkgMap))
-                    {
-                        // Create a candidate permutation that eliminates any candidates
-                        // that conflict with existing selected candidates.
-                        permutation = (permutation != null)
-                            ? permutation
-                            : allCandidates.copy();
-                        rethrow = (rethrow != null)
-                            ? rethrow
-                            : new ResolveException(
-                                "Uses constraint violation. Unable to resolve bundle revision "
-                                + revision.getSymbolicName()
-                                + " [" + revision
-                                + "] because it is exposed to package '"
-                                + pkgName
-                                + "' from bundle revisions "
-                                + importBlame.m_cap.getRevision().getSymbolicName()
-                                + " [" + importBlame.m_cap.getRevision()
-                                + "] and "
-                                + usedBlame.m_cap.getRevision().getSymbolicName()
-                                + " [" + usedBlame.m_cap.getRevision()
-                                + "] via two dependency chains.\n\nChain 1:\n"
-                                + toStringBlame(rc, allCandidates, importBlame)
-                                + "\n\nChain 2:\n"
-                                + toStringBlame(rc, allCandidates, usedBlame),
-                                null,
-                                null);
-
-                        mutated = (mutated != null)
-                            ? mutated
-                            : new HashSet();
-
-                        for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
-                        {
-                            BundleRequirement req = usedBlame.m_reqs.get(reqIdx);
-
-                            // If we've already permutated this requirement in another
-                            // uses constraint, don't permutate it again just continue
-                            // with the next uses constraint.
-                            if (mutated.contains(req))
-                            {
-                                break;
-                            }
-
-                            // See if we can permutate the candidates for blamed
-                            // requirement; there may be no candidates if the revision
-                            // associated with the requirement is already resolved.
-                            List<BundleCapability> candidates = permutation.getCandidates(req);
-                            if ((candidates != null) && (candidates.size() > 1))
-                            {
-                                mutated.add(req);
-                                // Remove the conflicting candidate.
-                                candidates.remove(0);
-                                // Continue with the next uses constraint.
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                // If there was a uses conflict, then we should add a uses
-                // permutation if we were able to permutate any candidates.
-                // Additionally, we should try to push an import permutation
-                // for the original import to force a backtracking on the
-                // original candidate decision if no viable candidate is found
-                // for the conflicting uses constraint.
-                if (rethrow != null)
-                {
-                    // Add uses permutation if we mutated any candidates.
-                    if (mutated.size() > 0)
-                    {
-                        m_usesPermutations.add(permutation);
-                    }
-
-                    // Try to permutate the candidate for the original
-                    // import requirement; only permutate it if we haven't
-                    // done so already.
-                    BundleRequirement req = importBlame.m_reqs.get(0);
-                    if (!mutated.contains(req))
-                    {
-                        // Since there may be lots of uses constraint violations
-                        // with existing import decisions, we may end up trying
-                        // to permutate the same import a lot of times, so we should
-                        // try to check if that the case and only permutate it once.
-                        permutateIfNeeded(allCandidates, req, m_importPermutations);
-                    }
-
-                    m_logger.log(
-                        Logger.LOG_DEBUG,
-                        "Candidate permutation failed due to a conflict between "
-                        + "imports; will try another if possible.",
-                        rethrow);
-                    throw rethrow;
-                }
-            }
-        }
-
-        resultCache.put(revision, Boolean.TRUE);
-
-        // Now check the consistency of all revisions on which the
-        // current revision depends. Keep track of the current number
-        // of permutations so we know if the lower level check was
-        // able to create a permutation or not in the case of failure.
-        int permCount = m_usesPermutations.size() + m_importPermutations.size();
-        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
-        {
-            for (Blame importBlame : entry.getValue())
-            {
-                if (!revision.equals(importBlame.m_cap.getRevision()))
-                {
-                    try
-                    {
-                        checkPackageSpaceConsistency(
-                            rc, false, importBlame.m_cap.getRevision(),
-                            allCandidates, revisionPkgMap, resultCache);
-                    }
-                    catch (ResolveException ex)
-                    {
-                        // If the lower level check didn't create any permutations,
-                        // then we should create an import permutation for the
-                        // requirement with the dependency on the failing revision
-                        // to backtrack on our current candidate selection.
-                        if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
-                        {
-                            BundleRequirement req = importBlame.m_reqs.get(0);
-                            permutate(allCandidates, req, m_importPermutations);
-                        }
-                        throw ex;
-                    }
-                }
-            }
-        }
-    }
-
-    private static void permutate(
-        Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
-    {
-        List<BundleCapability> candidates = allCandidates.getCandidates(req);
-        if (candidates.size() > 1)
-        {
-            Candidates perm = allCandidates.copy();
-            candidates = perm.getCandidates(req);
-            candidates.remove(0);
-            permutations.add(perm);
-        }
-    }
-
-    private static void permutateIfNeeded(
-        Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
-    {
-        List<BundleCapability> candidates = allCandidates.getCandidates(req);
-        if (candidates.size() > 1)
-        {
-            // Check existing permutations to make sure we haven't
-            // already permutated this requirement. This check for
-            // duplicate permutations is simplistic. It assumes if
-            // there is any permutation that contains a different
-            // initial candidate for the requirement in question,
-            // then it has already been permutated.
-            boolean permutated = false;
-            for (Candidates existingPerm : permutations)
-            {
-                List<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
-                if (!existingPermCands.get(0).equals(candidates.get(0)))
-                {
-                    permutated = true;
-                }
-            }
-            // If we haven't already permutated the existing
-            // import, do so now.
-            if (!permutated)
-            {
-                permutate(allCandidates, req, permutations);
-            }
-        }
-    }
-
-    private static void calculateExportedPackages(
-        BundleRevision revision,
-        Candidates allCandidates,
-        Map<BundleRevision, Packages> revisionPkgMap)
-    {
-        Packages packages = revisionPkgMap.get(revision);
-        if (packages != null)
-        {
-            return;
-        }
-        packages = new Packages(revision);
-
-        // Get all exported packages.
-        List<BundleCapability> caps = (revision.getWiring() != null)
-            ? revision.getWiring().getCapabilities(null)
-            : revision.getDeclaredCapabilities(null);
-        Map<String, BundleCapability> exports =
-            new HashMap<String, BundleCapability>(caps.size());
-        for (BundleCapability cap : caps)
-        {
-            if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-            {
-                if (!cap.getRevision().equals(revision))
-                {
-                    cap = new WrappedCapability(revision, (BundleCapabilityImpl) cap);
-                }
-                exports.put(
-                    (String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                    cap);
-            }
-        }
-        // Remove substitutable exports that were imported.
-        // For resolved revisions BundleWiring.getCapabilities()
-        // already excludes imported substitutable exports, but
-        // for resolving revisions we must look in the candidate
-        // map to determine which exports are substitutable.
-        if (!exports.isEmpty())
-        {
-            if (revision.getWiring() == null)
-            {
-                for (BundleRequirement req : revision.getDeclaredRequirements(null))
-                {
-                    if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                    {
-                        List<BundleCapability> cands = allCandidates.getCandidates(req);
-                        if ((cands != null) && !cands.isEmpty())
-                        {
-                            String pkgName = (String) cands.get(0)
-                                .getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
-                            exports.remove(pkgName);
-                        }
-                    }
-                }
-            }
-
-            // Add all non-substituted exports to the revisions's package space.
-            for (Entry<String, BundleCapability> entry : exports.entrySet())
-            {
-                packages.m_exportedPkgs.put(
-                    entry.getKey(), new Blame(entry.getValue(), null));
-            }
-        }
-
-        revisionPkgMap.put(revision, packages);
-    }
-
-    private boolean isCompatible(
-        BundleCapability currentCap, BundleCapability candCap,
-        Map<BundleRevision, Packages> revisionPkgMap)
-    {
-        if ((currentCap != null) && (candCap != null))
-        {
-            if (currentCap.equals(candCap))
-            {
-                return true;
-            }
-
-            List<BundleCapability> currentSources =
-                getPackageSources(
-                    currentCap,
-                    revisionPkgMap);
-            List<BundleCapability> candSources =
-                getPackageSources(
-                    candCap,
-                    revisionPkgMap);
-
-            return currentSources.containsAll(candSources)
-                || candSources.containsAll(currentSources);
-        }
-        return true;
-    }
-
-    private Map<BundleCapability, List<BundleCapability>> m_packageSourcesCache
-        = new HashMap();
-
-    private List<BundleCapability> getPackageSources(
-        BundleCapability cap, Map<BundleRevision, Packages> revisionPkgMap)
-    {
-        if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            List<BundleCapability> sources = m_packageSourcesCache.get(cap);
-            if (sources == null)
-            {
-                sources = getPackageSourcesInternal(
-                    cap, revisionPkgMap, new ArrayList(), new HashSet());
-                m_packageSourcesCache.put(cap, sources);
-            }
-            return sources;
-        }
-
-        if (!((BundleCapabilityImpl) cap).getUses().isEmpty())
-        {
-            List<BundleCapability> caps = new ArrayList<BundleCapability>(1);
-            caps.add(cap);
-            return caps;
-        }
-
-        return Collections.EMPTY_LIST;
-    }
-
-    private static List<BundleCapability> getPackageSourcesInternal(
-        BundleCapability cap, Map<BundleRevision, Packages> revisionPkgMap,
-        List<BundleCapability> sources, Set<BundleCapability> cycleMap)
-    {
-        if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            if (cycleMap.contains(cap))
-            {
-                return sources;
-            }
-            cycleMap.add(cap);
-
-            // Get the package name associated with the capability.
-            String pkgName = cap.getAttributes()
-                .get(BundleRevision.PACKAGE_NAMESPACE).toString();
-
-            // Since a revision can export the same package more than once, get
-            // all package capabilities for the specified package name.
-            List<BundleCapability> caps = (cap.getRevision().getWiring() != null)
-                ? cap.getRevision().getWiring().getCapabilities(null)
-                : cap.getRevision().getDeclaredCapabilities(null);
-            for (BundleCapability sourceCap : caps)
-            {
-                if (sourceCap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                    && sourceCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName))
-                {
-                    // Since capabilities may come from fragments, we need to check
-                    // for that case and wrap them.
-                    if (!cap.getRevision().equals(sourceCap.getRevision()))
-                    {
-                        sources.add(
-                            new WrappedCapability(cap.getRevision(), (BundleCapabilityImpl) sourceCap));
-                    }
-                    else
-                    {
-                        sources.add(sourceCap);
-                    }
-                }
-            }
-
-            // Then get any addition sources for the package from required bundles.
-            Packages pkgs = revisionPkgMap.get(cap.getRevision());
-            List<Blame> required = pkgs.m_requiredPkgs.get(pkgName);
-            if (required != null)
-            {
-                for (Blame blame : required)
-                {
-                    getPackageSourcesInternal(blame.m_cap, revisionPkgMap, sources, cycleMap);
-                }
-            }
-        }
-
-        return sources;
-    }
-
-    private static BundleRevision getDeclaringBundleRevision(BundleRevision br)
-    {
-        if (br instanceof WrappedRevision)
-        {
-            return ((WrappedRevision) br).getHost();
-        }
-        return br;
-    }
-
-    private static BundleCapability getDeclaredCapability(BundleCapability c)
-    {
-        if (c instanceof HostedCapability)
-        {
-            return ((HostedCapability) c).getDeclaredCapability();
-        }
-        return c;
-    }
-
-    private static BundleRequirement getDeclaredRequirement(BundleRequirement r)
-    {
-        if (r instanceof WrappedRequirement)
-        {
-            return ((WrappedRequirement) r).getOriginalRequirement();
-        }
-        return r;
-    }
-
-    private static Map<BundleRevision, List<ResolverWire>> populateWireMap(
-        BundleRevision revision, Map<BundleRevision, Packages> revisionPkgMap,
-        Map<BundleRevision, List<ResolverWire>> wireMap,
-        Candidates allCandidates)
-    {
-        BundleRevision unwrappedRevision = getDeclaringBundleRevision(revision);
-        if ((unwrappedRevision.getWiring() == null)
-            && !wireMap.containsKey(unwrappedRevision))
-        {
-            wireMap.put(unwrappedRevision, (List<ResolverWire>) Collections.EMPTY_LIST);
-
-            List<ResolverWire> packageWires = new ArrayList<ResolverWire>();
-            List<ResolverWire> bundleWires = new ArrayList<ResolverWire>();
-            List<ResolverWire> capabilityWires = new ArrayList<ResolverWire>();
-
-            for (BundleRequirement req : revision.getDeclaredRequirements(null))
-            {
-                List<BundleCapability> cands = allCandidates.getCandidates(req);
-                if ((cands != null) && (cands.size() > 0))
-                {
-                    BundleCapability cand = cands.get(0);
-                    // Ignore revisions that import themselves.
-                    if (!revision.equals(cand.getRevision()))
-                    {
-                        if (cand.getRevision().getWiring() == null)
-                        {
-                            populateWireMap(cand.getRevision(),
-                                revisionPkgMap, wireMap, allCandidates);
-                        }
-                        Packages candPkgs = revisionPkgMap.get(cand.getRevision());
-                        ResolverWire wire = new ResolverWireImpl(
-                            unwrappedRevision,
-                            getDeclaredRequirement(req),
-                            getDeclaringBundleRevision(cand.getRevision()),
-                            getDeclaredCapability(cand));
-                        if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                        {
-                            packageWires.add(wire);
-                        }
-                        else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
-                        {
-                            bundleWires.add(wire);
-                        }
-                        else
-                        {
-                            capabilityWires.add(wire);
-                        }
-                    }
-                }
-            }
-
-            // Combine package wires with require wires last.
-            packageWires.addAll(bundleWires);
-            packageWires.addAll(capabilityWires);
-            wireMap.put(unwrappedRevision, packageWires);
-
-            // Add host wire for any fragments.
-            if (revision instanceof WrappedRevision)
-            {
-                List<BundleRevision> fragments = ((WrappedRevision) revision).getFragments();
-                for (BundleRevision fragment : fragments)
-                {
-                    List<ResolverWire> hostWires = wireMap.get(fragment);
-                    if (hostWires == null)
-                    {
-                        hostWires = new ArrayList<ResolverWire>();
-                        wireMap.put(fragment, hostWires);
-                    }
-                    hostWires.add(
-                        new ResolverWireImpl(
-                            getDeclaringBundleRevision(fragment),
-                            fragment.getDeclaredRequirements(
-                                BundleRevision.HOST_NAMESPACE).get(0),
-                            unwrappedRevision,
-                            unwrappedRevision.getDeclaredCapabilities(
-                                BundleRevision.HOST_NAMESPACE).get(0)));
-                }
-            }
-        }
-
-        return wireMap;
-    }
-
-    private static Map<BundleRevision, List<ResolverWire>> populateDynamicWireMap(
-        BundleRevision revision, String pkgName, Map<BundleRevision, Packages> revisionPkgMap,
-        Map<BundleRevision, List<ResolverWire>> wireMap, Candidates allCandidates)
-    {
-        wireMap.put(revision, (List<ResolverWire>) Collections.EMPTY_LIST);
-
-        List<ResolverWire> packageWires = new ArrayList<ResolverWire>();
-
-        BundleRequirement dynReq = null;
-        BundleCapability dynCand = null;
-        for (BundleRequirement req
-            : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
-        {
-            // Get the candidates for the current dynamic requirement.
-            List<BundleCapability> candCaps = allCandidates.getCandidates(req);
-            // Optional requirements may not have any candidates.
-            if ((candCaps == null) || candCaps.isEmpty())
-            {
-                continue;
-            }
-
-            // Record the dynamic requirement.
-            dynReq = req;
-            dynCand = candCaps.get(0);
-
-            // Can only dynamically import one at a time, so break
-            // out of the loop after the first.
-            break;
-        }
-
-        if (dynReq != null)
-        {
-            if (dynCand.getRevision().getWiring() == null)
-            {
-                populateWireMap(dynCand.getRevision(), revisionPkgMap, wireMap,
-                    allCandidates);
-            }
-
-            packageWires.add(
-                new ResolverWireImpl(
-                    revision,
-                    dynReq,
-                    getDeclaringBundleRevision(dynCand.getRevision()),
-                    getDeclaredCapability(dynCand)));
-        }
-
-        wireMap.put(revision, packageWires);
-
-        return wireMap;
-    }
-
-    private static void dumpRevisionPkgMap(Map<BundleRevision, Packages> revisionPkgMap)
-    {
-        System.out.println("+++BUNDLE REVISION PKG MAP+++");
-        for (Entry<BundleRevision, Packages> entry : revisionPkgMap.entrySet())
-        {
-            dumpRevisionPkgs(entry.getKey(), entry.getValue());
-        }
-    }
-
-    private static void dumpRevisionPkgs(BundleRevision revision, Packages packages)
-    {
-        System.out.println(revision
-            + " (" + ((revision.getWiring() != null) ? "RESOLVED)" : "UNRESOLVED)"));
-        System.out.println("  EXPORTED");
-        for (Entry<String, Blame> entry : packages.m_exportedPkgs.entrySet())
-        {
-            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
-        }
-        System.out.println("  IMPORTED");
-        for (Entry<String, List<Blame>> entry : packages.m_importedPkgs.entrySet())
-        {
-            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
-        }
-        System.out.println("  REQUIRED");
-        for (Entry<String, List<Blame>> entry : packages.m_requiredPkgs.entrySet())
-        {
-            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
-        }
-        System.out.println("  USED");
-        for (Entry<String, List<Blame>> entry : packages.m_usedPkgs.entrySet())
-        {
-            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
-        }
-    }
-
-    private static String toStringBlame(
-        ResolveContext rc, Candidates allCandidates, Blame blame)
-    {
-        StringBuffer sb = new StringBuffer();
-        if ((blame.m_reqs != null) && !blame.m_reqs.isEmpty())
-        {
-            for (int i = 0; i < blame.m_reqs.size(); i++)
-            {
-                BundleRequirement req = blame.m_reqs.get(i);
-                sb.append("  ");
-                sb.append(req.getRevision().getSymbolicName());
-                sb.append(" [");
-                sb.append(req.getRevision().toString());
-                sb.append("]\n");
-                if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    sb.append("    import: ");
-                }
-                else
-                {
-                    sb.append("    require: ");
-                }
-                sb.append(((BundleRequirementImpl) req).getFilter().toString());
-                sb.append("\n     |");
-                if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    sb.append("\n    export: ");
-                }
-                else
-                {
-                    sb.append("\n    provide: ");
-                }
-                if ((i + 1) < blame.m_reqs.size())
-                {
-                    BundleCapability cap = getSatisfyingCapability(
-                        rc,
-                        allCandidates,
-                        blame.m_reqs.get(i));
-                    if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                    {
-                        sb.append(BundleRevision.PACKAGE_NAMESPACE);
-                        sb.append("=");
-                        sb.append(cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString());
-                        BundleCapability usedCap =
-                            getSatisfyingCapability(
-                                rc,
-                                allCandidates,
-                                blame.m_reqs.get(i + 1));
-                        sb.append("; uses:=");
-                        sb.append(usedCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
-                    }
-                    else
-                    {
-                        sb.append(cap);
-                    }
-                    sb.append("\n");
-                }
-                else
-                {
-                    BundleCapability export = getSatisfyingCapability(
-                        rc,
-                        allCandidates,
-                        blame.m_reqs.get(i));
-                    sb.append(export.getNamespace());
-                    sb.append("=");
-                    sb.append(export.getAttributes().get(export.getNamespace()).toString());
-                    if (export.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                        && !export.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE)
-                            .equals(blame.m_cap.getAttributes().get(
-                                BundleRevision.PACKAGE_NAMESPACE)))
-                    {
-                        sb.append("; uses:=");
-                        sb.append(blame.m_cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
-                        sb.append("\n    export: ");
-                        sb.append(BundleRevision.PACKAGE_NAMESPACE);
-                        sb.append("=");
-                        sb.append(blame.m_cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString());
-                    }
-                    sb.append("\n  ");
-                    sb.append(blame.m_cap.getRevision().getSymbolicName());
-                    sb.append(" [");
-                    sb.append(blame.m_cap.getRevision().toString());
-                    sb.append("]");
-                }
-            }
-        }
-        else
-        {
-            sb.append(blame.m_cap.getRevision().toString());
-        }
-        return sb.toString();
-    }
-
-    private static BundleCapability getSatisfyingCapability(
-        ResolveContext rc, Candidates allCandidates, BundleRequirement req)
-    {
-        BundleCapability cap = null;
-
-        // If the requiring revision is not resolved, then check in the
-        // candidate map for its matching candidate.
-        List<BundleCapability> cands = allCandidates.getCandidates(req);
-        if (cands != null)
-        {
-            cap = cands.get(0);
-        }
-        // Otherwise, if the requiring revision is resolved then check
-        // in its wires for the capability satisfying the requirement.
-        else if (rc.getWirings().containsKey(req.getRevision()))
-        {
-            List<BundleWire> wires = rc.getWirings().get(req.getRevision()).getRequiredWires(null);
-            req = getDeclaredRequirement(req);
-            for (BundleWire w : wires)
-            {
-                if (w.getRequirement().equals(req))
-                {
-// TODO: RESOLVER - This is not 100% correct, since requirements for
-//       dynamic imports with wildcards will reside on many wires and
-//       this code only finds the first one, not necessarily the correct
-//       one. This is only used for the diagnostic message, but it still
-//       could confuse the user.
-                    cap = w.getCapability();
-                    break;
-                }
-            }
-        }
-
-        return cap;
-    }
-
-    private static class Packages
-    {
-        private final BundleRevision m_revision;
-        public final Map<String, Blame> m_exportedPkgs = new HashMap();
-        public final Map<String, List<Blame>> m_importedPkgs = new HashMap();
-        public final Map<String, List<Blame>> m_requiredPkgs = new HashMap();
-        public final Map<String, List<Blame>> m_usedPkgs = new HashMap();
-        public boolean m_isCalculated = false;
-
-        public Packages(BundleRevision revision)
-        {
-            m_revision = revision;
-        }
-    }
-
-    private static class Blame
-    {
-        public final BundleCapability m_cap;
-        public final List<BundleRequirement> m_reqs;
-
-        public Blame(BundleCapability cap, List<BundleRequirement> reqs)
-        {
-            m_cap = cap;
-            m_reqs = reqs;
-        }
-
-        @Override
-        public String toString()
-        {
-            return m_cap.getRevision()
-                + "." + m_cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE)
-                + (((m_reqs == null) || m_reqs.isEmpty())
-                    ? " NO BLAME"
-                    : " BLAMED ON " + m_reqs);
-        }
-
-        @Override
-        public boolean equals(Object o)
-        {
-            return (o instanceof Blame) && m_reqs.equals(((Blame) o).m_reqs)
-                && m_cap.equals(((Blame) o).m_cap);
-        }
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
deleted file mode 100644
index 69162b9..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-public interface ResolverWire
-{
-    /**
-     * Returns the importing bundle revision.
-     * @return The importing bundle revision.
-    **/
-    public BundleRevision getRequirer();
-    /**
-     * Returns the associated requirement from the importing bundle revision
-     * that resulted in the creation of this wire.
-     * @return
-    **/
-    public BundleRequirement getRequirement();
-    /**
-     * Returns the exporting bundle revision.
-     * @return The exporting bundle revision.
-    **/
-    public BundleRevision getProvider();
-    /**
-     * Returns the associated capability from the exporting bundle revision
-     * that satisfies the requirement of the importing bundle revision.
-     * @return
-    **/
-    public BundleCapability getCapability();
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
deleted file mode 100644
index 4f8420f..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-
-class ResolverWireImpl implements ResolverWire
-{
-    private final BundleRevision m_requirer;
-    private final BundleRequirement m_req;
-    private final BundleRevision m_provider;
-    private final BundleCapability m_cap;
-
-    public ResolverWireImpl(
-        BundleRevision requirer, BundleRequirement req,
-        BundleRevision provider, BundleCapability cap)
-    {
-        m_requirer = requirer;
-        m_req = req;
-        m_provider = provider;
-        m_cap = cap;
-    }
-
-    public BundleRevision getRequirer()
-    {
-        return m_requirer;
-    }
-
-    public BundleRequirement getRequirement()
-    {
-        return m_req;
-    }
-
-    public BundleRevision getProvider()
-    {
-        return m_provider;
-    }
-
-    public BundleCapability getCapability()
-    {
-        return m_cap;
-    }
-
-    public String toString()
-    {
-        return m_req
-            + " -> "
-            + "[" + m_provider + "]";
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ShadowList.java b/framework/src/main/java/org/apache/felix/framework/resolver/ShadowList.java
deleted file mode 100644
index e64b559..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ShadowList.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-public class ShadowList<T> implements List<T>
-{
-    private final List<T> m_original;
-    private final List<T> m_shadow;
-
-    public ShadowList(List<T> original)
-    {
-        m_original = original;
-        m_shadow = new ArrayList<T>(original);
-    }
-
-    public List<T> getOriginal()
-    {
-        return m_original;
-    }
-
-    public int size()
-    {
-        return m_shadow.size();
-    }
-
-    public boolean isEmpty()
-    {
-        return m_shadow.isEmpty();
-    }
-
-    public boolean contains(Object o)
-    {
-        return m_shadow.contains(o);
-    }
-
-    public Iterator<T> iterator()
-    {
-        return m_shadow.iterator();
-    }
-
-    public Object[] toArray()
-    {
-        return m_shadow.toArray();
-    }
-
-    public <T> T[] toArray(T[] ts)
-    {
-        return m_shadow.toArray(ts);
-    }
-
-    public boolean add(T e)
-    {
-        return m_shadow.add(e);
-    }
-
-    public boolean remove(Object o)
-    {
-        return m_shadow.remove(o);
-    }
-
-    public boolean containsAll(Collection<?> clctn)
-    {
-        return m_shadow.containsAll(clctn);
-    }
-
-    public boolean addAll(Collection<? extends T> clctn)
-    {
-        return m_shadow.addAll(clctn);
-    }
-
-    public boolean addAll(int i, Collection<? extends T> clctn)
-    {
-        return m_shadow.addAll(i, clctn);
-    }
-
-    public boolean removeAll(Collection<?> clctn)
-    {
-        return m_shadow.removeAll(clctn);
-    }
-
-    public boolean retainAll(Collection<?> clctn)
-    {
-        return m_shadow.retainAll(clctn);
-    }
-
-    public void clear()
-    {
-        m_shadow.clear();
-    }
-
-    public T get(int i)
-    {
-        return m_shadow.get(i);
-    }
-
-    public T set(int i, T e)
-    {
-        return m_shadow.set(i, e);
-    }
-
-    public void add(int i, T e)
-    {
-        m_shadow.add(i, e);
-    }
-
-    public T remove(int i)
-    {
-        return m_shadow.remove(i);
-    }
-
-    public int indexOf(Object o)
-    {
-        return m_shadow.indexOf(o);
-    }
-
-    public int lastIndexOf(Object o)
-    {
-        return m_shadow.lastIndexOf(o);
-    }
-
-    public ListIterator<T> listIterator()
-    {
-        return m_shadow.listIterator();
-    }
-
-    public ListIterator<T> listIterator(int i)
-    {
-        return m_shadow.listIterator(i);
-    }
-
-    public List<T> subList(int i, int i1)
-    {
-        return m_shadow.subList(i, i1);
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
deleted file mode 100644
index 89b2984..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.Map;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-
-class SimpleHostedCapability implements HostedCapability
-{
-    private final BundleRevision m_host;
-    private final BundleCapability m_cap;
-
-    SimpleHostedCapability(BundleRevision host, BundleCapability cap)
-    {
-        m_host = host;
-        m_cap = cap;
-    }
-
-    public BundleRevision getResource()
-    {
-        return m_host;
-    }
-
-    public BundleRevision getRevision()
-    {
-        return m_host;
-    }
-
-    public BundleCapability getDeclaredCapability()
-    {
-        return m_cap;
-    }
-
-    public String getNamespace()
-    {
-        return m_cap.getNamespace();
-    }
-
-    public Map<String, String> getDirectives()
-    {
-        return m_cap.getDirectives();
-    }
-
-    public Map<String, Object> getAttributes()
-    {
-        return m_cap.getAttributes();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
deleted file mode 100644
index ee159ff..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.apache.felix.framework.resolver;
-
-import java.util.List;
-import java.util.Map;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Resource;
-
-public class WrappedCapability extends BundleCapabilityImpl implements HostedCapability
-{
-    private final BundleRevision m_host;
-    private final BundleCapabilityImpl m_cap;
-
-    public WrappedCapability(BundleRevision host, BundleCapabilityImpl cap)
-    {
-        super(host, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
-        m_host = host;
-        m_cap = cap;
-    }
-
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (obj == null)
-        {
-            return false;
-        }
-        if (getClass() != obj.getClass())
-        {
-            return false;
-        }
-        final WrappedCapability other = (WrappedCapability) obj;
-        if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
-        {
-            return false;
-        }
-        if (m_cap != other.m_cap && (m_cap == null || !m_cap.equals(other.m_cap)))
-        {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode()
-    {
-        int hash = 7;
-        hash = 37 * hash + (m_host != null ? m_host.hashCode() : 0);
-        hash = 37 * hash + (m_cap != null ? m_cap.hashCode() : 0);
-        return hash;
-    }
-
-    public BundleCapability getDeclaredCapability()
-    {
-        return m_cap;
-    }
-
-    @Override
-    public BundleRevision getResource()
-    {
-        return m_host;
-    }
-
-    @Override
-    public BundleRevision getRevision()
-    {
-        return m_host;
-    }
-
-    @Override
-    public String getNamespace()
-    {
-        return m_cap.getNamespace();
-    }
-
-    @Override
-    public Map<String, String> getDirectives()
-    {
-        return m_cap.getDirectives();
-    }
-
-    @Override
-    public Map<String, Object> getAttributes()
-    {
-        return m_cap.getAttributes();
-    }
-
-    @Override
-    public List<String> getUses()
-    {
-        return m_cap.getUses();
-    }
-
-    @Override
-    public String toString()
-    {
-        if (m_host == null)
-        {
-            return getAttributes().toString();
-        }
-        if (getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            return "[" + m_host + "] "
-                + getNamespace()
-                + "; "
-                + getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
-        }
-        return "[" + m_host + "] " + getNamespace() + "; " + getAttributes();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
deleted file mode 100644
index c0d15e0..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.Map;
-import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.wiring.BundleRevision;
-
-public class WrappedRequirement extends BundleRequirementImpl
-{
-    private final BundleRevision m_host;
-    private final BundleRequirementImpl m_req;
-
-    public WrappedRequirement(BundleRevision host, BundleRequirementImpl req)
-    {
-        super(host, req.getNamespace(), req.getDirectives(), req.getAttributes());
-        m_host = host;
-        m_req = req;
-    }
-
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (obj == null)
-        {
-            return false;
-        }
-        if (getClass() != obj.getClass())
-        {
-            return false;
-        }
-        final WrappedRequirement other = (WrappedRequirement) obj;
-        if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
-        {
-            return false;
-        }
-        if (m_req != other.m_req && (m_req == null || !m_req.equals(other.m_req)))
-        {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode()
-    {
-        int hash = 7;
-        hash = 37 * hash + (m_host != null ? m_host.hashCode() : 0);
-        hash = 37 * hash + (m_req != null ? m_req.hashCode() : 0);
-        return hash;
-    }
-
-    public BundleRequirementImpl getOriginalRequirement()
-    {
-        return m_req;
-    }
-
-    @Override
-    public BundleRevision getRevision()
-    {
-        return m_host;
-    }
-
-    @Override
-    public String getNamespace()
-    {
-        return m_req.getNamespace();
-    }
-
-    @Override
-    public SimpleFilter getFilter()
-    {
-        return m_req.getFilter();
-    }
-
-    @Override
-    public boolean isOptional()
-    {
-        return m_req.isOptional();
-    }
-
-    @Override
-    public Map<String, String> getDirectives()
-    {
-        return m_req.getDirectives();
-    }
-
-    @Override
-    public Map<String, Object> getAttributes()
-    {
-        return m_req.getAttributes();
-    }
-
-    @Override
-    public String toString()
-    {
-        return "[" + m_host + "] " + getNamespace() + "; " + getFilter().toString();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
deleted file mode 100644
index fa4ab5d..0000000
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.resolver;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.felix.framework.util.ImmutableList;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-class WrappedRevision implements BundleRevision
-{
-    private final BundleRevision m_host;
-    private final List<BundleRevision> m_fragments;
-    private List<BundleCapability> m_cachedCapabilities = null;
-    private List<BundleRequirement> m_cachedRequirements = null;
-
-    public WrappedRevision(BundleRevision host, List<BundleRevision> fragments)
-    {
-        m_host = host;
-        m_fragments = fragments;
-    }
-
-    public BundleRevision getHost()
-    {
-        return m_host;
-    }
-
-    public List<BundleRevision> getFragments()
-    {
-        return m_fragments;
-    }
-
-    public String getSymbolicName()
-    {
-        return m_host.getSymbolicName();
-    }
-
-    public Version getVersion()
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public List<Capability> getCapabilities(String namespace)
-    {
-        return asCapabilityList(getDeclaredCapabilities(namespace));
-    }
-
-    private static List<Capability> asCapabilityList(List caps)
-    {
-        return (List<Capability>) caps;
-    }
-
-    public List<BundleCapability> getDeclaredCapabilities(String namespace)
-    {
-        if (m_cachedCapabilities == null)
-        {
-            List<BundleCapability> caps = new ArrayList<BundleCapability>();
-
-            // Wrap host capabilities.
-            for (BundleCapability cap : m_host.getDeclaredCapabilities(null))
-            {
-                caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
-            }
-
-            // Wrap fragment capabilities.
-            if (m_fragments != null)
-            {
-                for (BundleRevision fragment : m_fragments)
-                {
-                    for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
-                    {
-// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
-//       that will need to be excluded from here.
-                        caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
-                    }
-                }
-            }
-            m_cachedCapabilities = ImmutableList.newInstance(caps);
-        }
-        return m_cachedCapabilities;
-    }
-
-    public List<Requirement> getRequirements(String namespace)
-    {
-        return asRequirementList(getDeclaredRequirements(namespace));
-    }
-
-    private static List<Requirement> asRequirementList(List reqs)
-    {
-        return (List<Requirement>) reqs;
-    }
-
-    public List<BundleRequirement> getDeclaredRequirements(String namespace)
-    {
-        if (m_cachedRequirements == null)
-        {
-            List<BundleRequirement> reqs = new ArrayList<BundleRequirement>();
-
-            // Wrap host requirements.
-            for (BundleRequirement req : m_host.getDeclaredRequirements(null))
-            {
-                reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
-            }
-
-            // Wrap fragment requirements.
-            if (m_fragments != null)
-            {
-                for (BundleRevision fragment : m_fragments)
-                {
-                    for (BundleRequirement req : fragment.getDeclaredRequirements(null))
-                    {
-                        if (!req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-                        {
-                            reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
-                        }
-                    }
-                }
-            }
-            m_cachedRequirements = ImmutableList.newInstance(reqs);
-        }
-        return m_cachedRequirements;
-    }
-
-    public int getTypes()
-    {
-        return m_host.getTypes();
-    }
-
-    public BundleWiring getWiring()
-    {
-        return null;
-    }
-
-    public Bundle getBundle()
-    {
-        return m_host.getBundle();
-    }
-
-    @Override
-    public String toString()
-    {
-        return m_host.toString();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index 8128aa1..3298a27 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -18,7 +18,11 @@
  */
 package org.apache.felix.framework.util;
 
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URL;
 import java.security.SecureRandom;
 import java.util.ArrayList;
@@ -31,9 +35,6 @@
 import java.util.Set;
 
 import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
@@ -42,6 +43,7 @@
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Resource;
 
 public class Util
 {
@@ -665,7 +667,7 @@
                 {
                     if (entry.getKey().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE))
                     {
-                        return Boolean.valueOf((String) entry.getValue());
+                        return Boolean.valueOf(entry.getValue());
                     }
                 }
                 // Can only have one bundle capability, so break.
@@ -687,6 +689,14 @@
         return ((revision.getTypes() & BundleRevision.TYPE_FRAGMENT) > 0);
     }
 
+    public static boolean isFragment(Resource resource)
+    {
+        if (resource instanceof BundleRevision)
+            return isFragment((BundleRevision) resource);
+        else
+            return false;
+    }
+
     public static List<BundleRevision> getFragments(BundleWiring wiring)
     {
         List<BundleRevision> fragments = Collections.EMPTY_LIST;
