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 ce063cb..287087e 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -1928,7 +1928,7 @@
                                 {
                                     try
                                     {
-                                        m_revision.getSecureAction()
+                                        BundleRevisionImpl.getSecureAction()
                                             .invokeWeavingHook(wh, wci);
                                     }
                                     catch (Throwable th)
@@ -2531,7 +2531,7 @@
                 BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
             BundleRequirementImpl req = new BundleRequirementImpl(
                 revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
-            Set<BundleCapability> exporters = resolver.getCandidates(req, false);
+            List<BundleCapability> exporters = resolver.findProviders(req, false);
 
             BundleRevision provider = null;
             try
@@ -2570,7 +2570,7 @@
             BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
         BundleRequirementImpl req = new BundleRequirementImpl(
             revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<BundleCapability> exports = resolver.getCandidates(req, false);
+        List<BundleCapability> exports = resolver.findProviders(req, false);
         if (exports.size() > 0)
         {
             boolean classpath = false;
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 46a1162..dc1e144 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3564,7 +3564,7 @@
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        Set<BundleCapability> exports = m_resolver.getCandidates(req, false);
+        List<BundleCapability> exports = m_resolver.findProviders(req, false);
 
         // We only want resolved capabilities.
         for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); )
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
new file mode 100644
index 0000000..c3a136f
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+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.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ *
+ * @author rickhall
+ */
+public class ResolveContextImpl extends ResolveContext
+{
+    private final StatefulResolver m_state;
+    private final Map<BundleRevision, BundleWiring> m_wirings;
+    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,
+        Collection<BundleRevision> mandatory, Collection<BundleRevision> optional,
+        Collection<BundleRevision> ondemand)
+    {
+        m_state = state;
+        m_wirings = wirings;
+        m_mandatory = mandatory;
+        m_optional = optional;
+        m_ondemand = ondemand;
+    }
+
+    @Override
+    public Collection<BundleRevision> getMandatoryRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_mandatory);
+    }
+
+    @Override
+    public Collection<BundleRevision> getOptionalRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_optional);
+    }
+
+    public Collection<BundleRevision> getOndemandRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_ondemand);
+    }
+
+    public List<BundleCapability> findProviders(BundleRequirement br, boolean obeyMandatory)
+    {
+        return m_state.findProviders(br, obeyMandatory);
+    }
+
+    public int insertHostedCapability(List<BundleCapability> caps, HostedCapability hc)
+    {
+        int idx = Collections.binarySearch(caps, hc, new CandidateComparator());
+        if (idx < 0)
+        {
+            idx = Math.abs(idx + 1);
+        }
+        caps.add(idx, hc);
+        return idx;
+    }
+
+    public boolean isEffective(BundleRequirement br)
+    {
+        return m_state.isEffective(br);
+    }
+
+    public Map<BundleRevision, BundleWiring> getWirings()
+    {
+        return m_wirings;
+    }
+
+    public void checkExecutionEnvironment(BundleRevision rev) throws ResolveException
+    {
+        m_state.checkExecutionEnvironment(rev);
+    }
+
+    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/StatefulResolver.java b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
index c099f15..376ffcb 100644
--- a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
@@ -28,9 +28,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.StringTokenizer;
-import java.util.TreeSet;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.CandidateComparator;
@@ -64,33 +62,265 @@
     private final Logger m_logger;
     private final Felix m_felix;
     private final Resolver m_resolver;
-    private final ResolverStateImpl m_resolverState;
     private final List<ResolverHook> m_hooks = new ArrayList<ResolverHook>();
     private boolean m_isResolving = false;
     private Collection<BundleRevision> m_whitelist = null;
 
+    // Set of all revisions.
+    private final Set<BundleRevision> m_revisions;
+    // Set of all fragments.
+    private final Set<BundleRevision> m_fragments;
+    // Capability sets.
+    private final Map<String, CapabilitySet> m_capSets;
+    // Maps singleton symbolic names to list of bundle revisions sorted by version.
+    private final Map<String, List<BundleRevision>> m_singletons;
+    // Selected singleton bundle revisions.
+    private final Set<BundleRevision> m_selectedSingletons;
+    // Execution environment.
+    private final String m_fwkExecEnvStr;
+    // Parsed framework environments
+    private final Set<String> m_fwkExecEnvSet;
+
     StatefulResolver(Felix felix)
     {
         m_felix = felix;
         m_logger = m_felix.getLogger();
         m_resolver = new ResolverImpl(m_logger);
-        m_resolverState = new ResolverStateImpl(
-            (String) m_felix.getConfig().get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT));
+
+        m_revisions = new HashSet<BundleRevision>();
+        m_fragments = new HashSet<BundleRevision>();
+        m_capSets = new HashMap<String, CapabilitySet>();
+        m_singletons = new HashMap<String, List<BundleRevision>>();
+        m_selectedSingletons = new HashSet<BundleRevision>();
+
+        String fwkExecEnvStr =
+            (String) m_felix.getConfig().get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
+        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
+
+        List<String> indices = new ArrayList<String>();
+        indices.add(BundleRevision.BUNDLE_NAMESPACE);
+        m_capSets.put(BundleRevision.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(BundleRevision.PACKAGE_NAMESPACE);
+        m_capSets.put(BundleRevision.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(BundleRevision.HOST_NAMESPACE);
+        m_capSets.put(BundleRevision.HOST_NAMESPACE,  new CapabilitySet(indices, true));
     }
 
-    void addRevision(BundleRevision br)
+    synchronized void addRevision(BundleRevision br)
     {
-        m_resolverState.addRevision(br);
+        // Always attempt to remove the revision, since
+        // this method can be used for re-indexing a revision
+        // after it has been resolved.
+        removeRevision(br);
+
+        m_revisions.add(br);
+
+        // Add singletons to the singleton map.
+        boolean isSingleton = Util.isSingleton(br);
+        if (isSingleton)
+        {
+            // Index the new singleton.
+            addToSingletonMap(m_singletons, br);
+        }
+
+        // We always need to index non-singleton bundle capabilities, but
+        // singleton bundles only need to be index if they are resolved.
+        // Unresolved singleton capabilities are only indexed before a
+        // resolve operation when singleton selection is performed.
+        if (!isSingleton || (br.getWiring() != null))
+        {
+            if (Util.isFragment(br))
+            {
+                m_fragments.add(br);
+            }
+            indexCapabilities(br);
+        }
     }
 
-    void removeRevision(BundleRevision br)
+    synchronized void removeRevision(BundleRevision br)
     {
-        m_resolverState.removeRevision(br);
+        if (m_revisions.remove(br))
+        {
+            m_fragments.remove(br);
+            deindexCapabilities(br);
+
+            // If this module is a singleton, then remove it from the
+            // singleton map.
+            List<BundleRevision> revisions = m_singletons.get(br.getSymbolicName());
+            if (revisions != null)
+            {
+                revisions.remove(br);
+                if (revisions.isEmpty())
+                {
+                    m_singletons.remove(br.getSymbolicName());
+                }
+            }
+        }
     }
 
-    Set<BundleCapability> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
+    boolean isEffective(BundleRequirement req)
     {
-        return m_resolverState.getCandidates(req, obeyMandatory);
+        String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+        return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
+    }
+
+    synchronized List<BundleCapability> findProviders(
+        BundleRequirement req, boolean obeyMandatory)
+    {
+        BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
+        List<BundleCapability> result = new ArrayList<BundleCapability>();
+
+        CapabilitySet capSet = m_capSets.get(req.getNamespace());
+        if (capSet != null)
+        {
+            // Get the requirement's filter; if this is our own impl we
+            // have a shortcut to get the already parsed filter, otherwise
+            // we must parse it from the directive.
+            SimpleFilter sf = null;
+            if (req instanceof BundleRequirementImpl)
+            {
+                sf = ((BundleRequirementImpl) req).getFilter();
+            }
+            else
+            {
+                String filter = req.getDirectives().get(Constants.FILTER_DIRECTIVE);
+                if (filter == null)
+                {
+                    sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+                }
+                else
+                {
+                    sf = SimpleFilter.parse(filter);
+                }
+            }
+
+            // Find the matching candidates.
+            Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
+            // Filter matching candidates.
+            for (BundleCapability cap : matches)
+            {
+                // Filter according to security.
+                if (filteredBySecurity(req, cap))
+                {
+                    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))
+                {
+                    continue;
+                }
+
+                result.add(cap);
+            }
+        }
+
+        // If we have resolver hooks, then we may need to filter our results
+        // based on a whitelist and/or fine-grained candidate filtering.
+        if (!result.isEmpty() && !m_hooks.isEmpty())
+        {
+            // It we have a whitelist, then first filter out candidates
+            // from disallowed revisions.
+            if (m_whitelist != null)
+            {
+                for (Iterator<BundleCapability> it = result.iterator(); it.hasNext(); )
+                {
+                    if (!m_whitelist.contains(it.next().getRevision()))
+                    {
+                        it.remove();
+                    }
+                }
+            }
+
+            // Now give the hooks a chance to do fine-grained filtering.
+            ShrinkableCollection<BundleCapability> shrinkable =
+                new ShrinkableCollection<BundleCapability>(result);
+            for (ResolverHook hook : m_hooks)
+            {
+                try
+                {
+                    Felix.m_secureAction
+                        .invokeResolverHookMatches(hook, req, shrinkable);
+                }
+                catch (Throwable th)
+                {
+                    m_logger.log(Logger.LOG_WARNING, "Resolver hook exception.", th);
+                }
+            }
+        }
+
+        Collections.sort(result, new CandidateComparator());
+
+        return result;
+    }
+
+    private boolean filteredBySecurity(BundleRequirement req, BundleCapability cap)
+    {
+        if (System.getSecurityManager() != null)
+        {
+            BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
+
+            if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
+            {
+                if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
+                    PackagePermission.EXPORTONLY)) ||
+                    !((reqRevision == null) ||
+                        ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                            new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
+                            cap.getRevision().getBundle(),PackagePermission.IMPORT))
+                    ))
+                {
+                    if (reqRevision != cap.getRevision())
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
+            {   if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
+                    !((reqRevision == null) ||
+                        ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                            new BundlePermission(reqRevision.getSymbolicName(), BundlePermission.REQUIRE))
+                    ))
+                {
+                    return true;
+                }
+            }
+            else if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
+            {
+                if (!((BundleProtectionDomain) reqRevision.getProtectionDomain())
+                    .impliesDirect(new BundlePermission(
+                        reqRevision.getSymbolicName(),
+                        BundlePermission.FRAGMENT))
+                || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain())
+                    .impliesDirect(new BundlePermission(
+                        cap.getRevision().getSymbolicName(),
+                        BundlePermission.HOST)))
+                {
+                    return true;
+                }
+            }
+            else  if (!req.getNamespace().equals("osgi.ee"))
+            {
+                if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new CapabilityPermission(req.getNamespace(), CapabilityPermission.PROVIDE))
+                    ||
+                    !((reqRevision == null) || ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                    new CapabilityPermission(req.getNamespace(), cap.getAttributes(), cap.getRevision().getBundle(), CapabilityPermission.REQUIRE))))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     void resolve(
@@ -129,7 +359,7 @@
                 prepareResolverHooks(mandatory, optional);
 
             // Select any singletons in the resolver state.
-            m_resolverState.selectSingletons();
+            selectSingletons();
 
             // Extensions are resolved differently.
             for (Iterator<BundleRevision> it = mandatory.iterator(); it.hasNext(); )
@@ -140,7 +370,7 @@
                 {
                     it.remove();
                 }
-                else if (Util.isSingleton(br) && !m_resolverState.isSelectedSingleton(br))
+                else if (Util.isSingleton(br) && !isSelectedSingleton(br))
                 {
                     throw new ResolveException("Singleton conflict.", br, null);
                 }
@@ -153,7 +383,7 @@
                 {
                     it.remove();
                 }
-                else if (Util.isSingleton(br) && !m_resolverState.isSelectedSingleton(br))
+                else if (Util.isSingleton(br) && !isSelectedSingleton(br))
                 {
                     it.remove();
                 }
@@ -166,10 +396,12 @@
             {
                 // Resolve the revision.
                 wireMap = m_resolver.resolve(
-                    m_resolverState,
-                    mandatory,
-                    optional,
-                    m_resolverState.getFragments());
+                    new ResolveContextImpl(
+                        this,
+                        getWirings(),
+                        mandatory,
+                        optional,
+                        getFragments()));
             }
             catch (ResolveException ex)
             {
@@ -249,7 +481,7 @@
                             Collections.singleton(revision), Collections.EMPTY_SET);
 
                     // Select any singletons in the resolver state.
-                    m_resolverState.selectSingletons();
+                    selectSingletons();
 
                     // Catch any resolve exception to rethrow later because
                     // we may need to call end() on resolver hooks.
@@ -257,8 +489,13 @@
                     try
                     {
                         wireMap = m_resolver.resolve(
-                            m_resolverState, revision, pkgName,
-                            m_resolverState.getFragments());
+                            new ResolveContextImpl(
+                                this,
+                                getWirings(),
+                                Collections.EMPTY_LIST,
+                                Collections.EMPTY_LIST,
+                                getFragments()),
+                            revision, pkgName);
                     }
                     catch (ResolveException ex)
                     {
@@ -373,9 +610,7 @@
             }
 
             // Ask hooks to indicate which revisions should not be resolved.
-            m_whitelist =
-                new ShrinkableCollection<BundleRevision>(
-                    m_resolverState.getUnresolvedRevisions());
+            m_whitelist = new ShrinkableCollection<BundleRevision>(getUnresolvedRevisions());
             int originalSize = m_whitelist.size();
             for (ResolverHook hook : m_hooks)
             {
@@ -518,7 +753,7 @@
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        Set<BundleCapability> candidates = m_resolverState.getCandidates(req, false);
+        List<BundleCapability> candidates = findProviders(req, false);
 
         return !candidates.isEmpty();
     }
@@ -713,7 +948,7 @@
                 // Reindex the revision's capabilities since its resolved
                 // capabilities could be different than its declared ones
                 // (e.g., due to substitutable exports).
-                m_resolverState.addRevision(revision);
+                addRevision(revision);
 
                 // Update the state of the revision's bundle to resolved as well.
                 markBundleResolved(revision);
@@ -855,635 +1090,378 @@
         return pkgs;
     }
 
-    class ResolverStateImpl implements Resolver.ResolverState
+    private synchronized void indexCapabilities(BundleRevision br)
     {
-        // Set of all revisions.
-        private final Set<BundleRevision> m_revisions;
-        // Set of all fragments.
-        private final Set<BundleRevision> m_fragments;
-        // Capability sets.
-        private final Map<String, CapabilitySet> m_capSets;
-        // Maps singleton symbolic names to list of bundle revisions sorted by version.
-        private final Map<String, List<BundleRevision>> m_singletons;
-        // Selected singleton bundle revisions.
-        private final Set<BundleRevision> m_selectedSingletons;
-        // Execution environment.
-        private final String m_fwkExecEnvStr;
-        // Parsed framework environments
-        private final Set<String> m_fwkExecEnvSet;
-
-//    void dump()
-//    {
-//        for (Entry<String, CapabilitySet> entry : m_capSets.entrySet())
-//        {
-//            System.out.println("+++ START CAPSET " + entry.getKey());
-//            entry.getValue().dump();
-//            System.out.println("+++ END CAPSET " + entry.getKey());
-//        }
-//    }
-
-        ResolverStateImpl(String fwkExecEnvStr)
+        List<BundleCapability> caps =
+            (Util.isFragment(br) || (br.getWiring() == null))
+                ? br.getDeclaredCapabilities(null)
+                : br.getWiring().getCapabilities(null);
+        if (caps != null)
         {
-            m_revisions = new HashSet<BundleRevision>();
-            m_fragments = new HashSet<BundleRevision>();
-            m_capSets = new HashMap<String, CapabilitySet>();
-            m_singletons = new HashMap<String, List<BundleRevision>>();
-            m_selectedSingletons = new HashSet<BundleRevision>();
-
-            m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
-            m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
-
-            List<String> indices = new ArrayList<String>();
-            indices.add(BundleRevision.BUNDLE_NAMESPACE);
-            m_capSets.put(BundleRevision.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
-
-            indices = new ArrayList<String>();
-            indices.add(BundleRevision.PACKAGE_NAMESPACE);
-            m_capSets.put(BundleRevision.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
-
-            indices = new ArrayList<String>();
-            indices.add(BundleRevision.HOST_NAMESPACE);
-            m_capSets.put(BundleRevision.HOST_NAMESPACE,  new CapabilitySet(indices, true));
-        }
-
-        synchronized Set<BundleRevision> getUnresolvedRevisions()
-        {
-            Set<BundleRevision> unresolved = new HashSet<BundleRevision>();
-            for (BundleRevision revision : m_revisions)
+            for (BundleCapability cap : caps)
             {
-                if (revision.getWiring() == null)
-                {
-                    unresolved.add(revision);
-                }
-            }
-            return unresolved;
-        }
-
-        synchronized void addRevision(BundleRevision br)
-        {
-            // Always attempt to remove the revision, since
-            // this method can be used for re-indexing a revision
-            // after it has been resolved.
-            removeRevision(br);
-
-            m_revisions.add(br);
-
-            // Add singletons to the singleton map.
-            boolean isSingleton = Util.isSingleton(br);
-            if (isSingleton)
-            {
-                // Index the new singleton.
-                addToSingletonMap(m_singletons, br);
-            }
-
-            // We always need to index non-singleton bundle capabilities, but
-            // singleton bundles only need to be index if they are resolved.
-            // Unresolved singleton capabilities are only indexed before a
-            // resolve operation when singleton selection is performed.
-            if (!isSingleton || (br.getWiring() != null))
-            {
-                if (Util.isFragment(br))
-                {
-                    m_fragments.add(br);
-                }
-                indexCapabilities(br);
-            }
-        }
-
-        private synchronized void indexCapabilities(BundleRevision br)
-        {
-            List<BundleCapability> caps =
-                (Util.isFragment(br) || (br.getWiring() == null))
-                    ? br.getDeclaredCapabilities(null)
-                    : br.getWiring().getCapabilities(null);
-            if (caps != null)
-            {
-                for (BundleCapability cap : caps)
-                {
-                    // If the capability is from a different revision, then
-                    // don't index it since it is a capability from a fragment.
-                    // In that case, the fragment capability is still indexed.
-                    // It will be the resolver's responsibility to find all
-                    // attached hosts for fragments.
-                    if (cap.getRevision() == br)
-                    {
-                        CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                        if (capSet == null)
-                        {
-                            capSet = new CapabilitySet(null, true);
-                            m_capSets.put(cap.getNamespace(), capSet);
-                        }
-                        capSet.addCapability(cap);
-                    }
-                }
-            }
-        }
-
-        private synchronized void deindexCapabilities(BundleRevision br)
-        {
-            // We only need be concerned with declared capabilities here,
-            // because resolved capabilities will be a subset, since fragment
-            // capabilities are not considered to be part of the host.
-            List<BundleCapability> caps = br.getDeclaredCapabilities(null);
-            if (caps != null)
-            {
-                for (BundleCapability cap : caps)
+                // If the capability is from a different revision, then
+                // don't index it since it is a capability from a fragment.
+                // In that case, the fragment capability is still indexed.
+                // It will be the resolver's responsibility to find all
+                // attached hosts for fragments.
+                if (cap.getRevision() == br)
                 {
                     CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                    if (capSet != null)
+                    if (capSet == null)
                     {
-                        capSet.removeCapability(cap);
+                        capSet = new CapabilitySet(null, true);
+                        m_capSets.put(cap.getNamespace(), capSet);
                     }
-                }
-            }
-        }
-
-        synchronized void removeRevision(BundleRevision br)
-        {
-            if (m_revisions.remove(br))
-            {
-                m_fragments.remove(br);
-                deindexCapabilities(br);
-
-                // If this module is a singleton, then remove it from the
-                // singleton map.
-                List<BundleRevision> revisions = m_singletons.get(br.getSymbolicName());
-                if (revisions != null)
-                {
-                    revisions.remove(br);
-                    if (revisions.isEmpty())
-                    {
-                        m_singletons.remove(br.getSymbolicName());
-                    }
-                }
-            }
-        }
-
-        synchronized Set<BundleRevision> getFragments()
-        {
-            Set<BundleRevision> fragments = new HashSet(m_fragments);
-            // Filter out any fragments that are not the current revision.
-            for (Iterator<BundleRevision> it = fragments.iterator(); it.hasNext(); )
-            {
-                BundleRevision fragment = it.next();
-                BundleRevision currentFragmentRevision =
-                    fragment.getBundle().adapt(BundleRevision.class);
-                if (fragment != currentFragmentRevision)
-                {
-                    it.remove();
-                }
-            }
-            return fragments;
-        }
-
-        synchronized boolean isSelectedSingleton(BundleRevision br)
-        {
-            return m_selectedSingletons.contains(br);
-        }
-
-        synchronized void selectSingletons()
-            throws BundleException
-        {
-            // First deindex any unresolved singletons to make sure
-            // there aren't any available from previous resolves.
-            // Also remove them from the fragment list, for the same
-            // reason.
-            m_selectedSingletons.clear();
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
-            {
-                for (BundleRevision singleton : entry.getValue())
-                {
-                    if (singleton.getWiring() == null)
-                    {
-                        deindexCapabilities(singleton);
-                        m_fragments.remove(singleton);
-                    }
-                }
-            }
-
-            // If no resolver hooks, then use default singleton selection
-            // algorithm, otherwise defer to the resolver hooks.
-            if (m_hooks.isEmpty())
-            {
-                selectDefaultSingletons();
-            }
-            else
-            {
-                selectSingletonsUsingHooks();
-            }
-        }
-
-        /*
-         * Selects the singleton with the highest version from groupings
-         * based on the symbolic name. No selection is made if the group
-         * already has a resolved singleton.
-         */
-        private void selectDefaultSingletons()
-        {
-            // Now select the singletons available for this resolve operation.
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
-            {
-                selectSingleton(entry.getValue());
-            }
-        }
-
-        /*
-         * Groups singletons based on resolver hook filtering and then selects
-         * the singleton from each group with the highest version that is in
-         * the resolver hook whitelist. No selection is made if a group already
-         * has a resolved singleton in it.
-         */
-        private void selectSingletonsUsingHooks()
-            throws BundleException
-        {
-            // Convert singleton bundle revision map into a map using
-            // bundle capabilities instead, since this is what the resolver
-            // hooks require.
-            Map<BundleCapability, Collection<BundleCapability>> allCollisions
-                = new HashMap<BundleCapability, Collection<BundleCapability>>();
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
-            {
-                Collection<BundleCapability> bundleCaps =
-                    new ArrayList<BundleCapability>();
-                for (BundleRevision br : entry.getValue())
-                {
-                    List<BundleCapability> caps =
-                        br.getDeclaredCapabilities(BundleRevision.BUNDLE_NAMESPACE);
-                    if (!caps.isEmpty())
-                    {
-                        bundleCaps.add(caps.get(0));
-                    }
-                }
-
-                for (BundleCapability bc : bundleCaps)
-                {
-                    Collection<BundleCapability> capCopy =
-                        new ShrinkableCollection<BundleCapability>(
-                            new ArrayList<BundleCapability>(bundleCaps));
-                    capCopy.remove(bc);
-                    allCollisions.put(bc, capCopy);
-                }
-            }
-
-            // Invoke hooks to allow them to filter singleton collisions.
-            for (ResolverHook hook : m_hooks)
-            {
-                for (Entry<BundleCapability, Collection<BundleCapability>> entry
-                    : allCollisions.entrySet())
-                {
-                    try
-                    {
-                        Felix.m_secureAction
-                            .invokeResolverHookSingleton(hook, entry.getKey(), entry.getValue());
-                    }
-                    catch (Throwable ex)
-                    {
-                        throw new BundleException(
-                            "Resolver hook exception: " + ex.getMessage(),
-                            BundleException.REJECTED_BY_HOOK,
-                            ex);
-                    }
-                }
-            }
-
-            // Create groups according to how the resolver hooks filtered the
-            // collisions.
-            List<List<BundleRevision>> groups = new ArrayList<List<BundleRevision>>();
-            while (!allCollisions.isEmpty())
-            {
-                BundleCapability target = allCollisions.entrySet().iterator().next().getKey();
-                groups.add(groupSingletons(allCollisions, target, new ArrayList<BundleRevision>()));
-            }
-
-            // Now select the singletons available for this resolve operation.
-            for (List<BundleRevision> group : groups)
-            {
-                selectSingleton(group);
-            }
-        }
-
-        private List<BundleRevision> groupSingletons(
-            Map<BundleCapability, Collection<BundleCapability>> allCollisions,
-            BundleCapability target, List<BundleRevision> group)
-        {
-            if (!group.contains(target.getRevision()))
-            {
-                // Add the target since it is implicitly part of the group.
-                group.add(target.getRevision());
-
-                // Recursively add the revisions of any singleton's in the
-                // target's collisions.
-                Collection<BundleCapability> collisions = allCollisions.remove(target);
-                for (BundleCapability collision : collisions)
-                {
-                    groupSingletons(allCollisions, collision, group);
-                }
-
-                // Need to check the values of other collisions for this target
-                // and add those to the target's group too, since collisions are
-                // treated as two-way relationships. Repeat until there are no
-                // collision groups left that contain the target capability.
-                boolean repeat;
-                do
-                {
-                    repeat = false;
-                    for (Entry<BundleCapability, Collection<BundleCapability>> entry:
-                        allCollisions.entrySet())
-                    {
-                        if (entry.getValue().contains(target))
-                        {
-                            repeat = true;
-                            groupSingletons(allCollisions, entry.getKey(), group);
-                            break;
-                        }
-                    }
-                }
-                while (repeat);
-            }
-            return group;
-        }
-
-        /*
-         * Selects the highest bundle revision from the group that is
-         * in the resolver hook whitelist (if there are hooks). No
-         * selection is made if there is an already resolved singleton
-         * in the group, since it is already indexed.
-         */
-        private void selectSingleton(List<BundleRevision> singletons)
-        {
-            BundleRevision selected = null;
-            for (BundleRevision singleton : singletons)
-            {
-                // If a singleton is already resolved,
-                // then there is nothing to do.
-                if (singleton.getWiring() != null)
-                {
-                    selected = null;
-                    break;
-                }
-                // If this singleton is not in the whitelist, then it cannot
-                // be selected. If it is, in can only be selected if it has
-                // a higher version than the currently selected singleton, if
-                // there is one.
-                if (((m_whitelist == null) || m_whitelist.contains(singleton))
-                    && ((selected == null)
-                        || (selected.getVersion().compareTo(singleton.getVersion()) > 0)))
-                {
-                    selected = singleton;
-                }
-            }
-            if (selected != null)
-            {
-                // Record the selected singleton.
-                m_selectedSingletons.add(selected);
-                // Index its capabilities.
-                indexCapabilities(selected);
-                // If the selected singleton is a fragment, then
-                // add it to the list of fragments.
-                if (Util.isFragment(selected))
-                {
-                    m_fragments.add(selected);
-                }
-            }
-        }
-
-        //
-        // ResolverState methods.
-        //
-
-        public boolean isEffective(BundleRequirement req)
-        {
-            String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
-            return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
-        }
-
-        public synchronized SortedSet<BundleCapability> getCandidates(
-            BundleRequirement req, boolean obeyMandatory)
-        {
-            BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
-            SortedSet<BundleCapability> result =
-                new TreeSet<BundleCapability>(new CandidateComparator());
-
-            CapabilitySet capSet = m_capSets.get(req.getNamespace());
-            if (capSet != null)
-            {
-                // Get the requirement's filter; if this is our own impl we
-                // have a shortcut to get the already parsed filter, otherwise
-                // we must parse it from the directive.
-                SimpleFilter sf = null;
-                if (req instanceof BundleRequirementImpl)
-                {
-                    sf = ((BundleRequirementImpl) req).getFilter();
-                }
-                else
-                {
-                    String filter = req.getDirectives().get(Constants.FILTER_DIRECTIVE);
-                    if (filter == null)
-                    {
-                        sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
-                    }
-                    else
-                    {
-                        sf = SimpleFilter.parse(filter);
-                    }
-                }
-
-                // Find the matching candidates.
-                Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
-                // Filter matching candidates.
-                for (BundleCapability cap : matches)
-                {
-                    // Filter according to security.
-                    if (filteredBySecurity(req, cap))
-                    {
-                        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))
-                    {
-                        continue;
-                    }
-
-                    result.add(cap);
-                }
-            }
-
-            // If we have resolver hooks, then we may need to filter our results
-            // based on a whitelist and/or fine-grained candidate filtering.
-            if (!result.isEmpty() && !m_hooks.isEmpty())
-            {
-                // It we have a whitelist, then first filter out candidates
-                // from disallowed revisions.
-                if (m_whitelist != null)
-                {
-                    for (Iterator<BundleCapability> it = result.iterator(); it.hasNext(); )
-                    {
-                        if (!m_whitelist.contains(it.next().getRevision()))
-                        {
-                            it.remove();
-                        }
-                    }
-                }
-
-                // Now give the hooks a chance to do fine-grained filtering.
-                ShrinkableCollection<BundleCapability> shrinkable =
-                    new ShrinkableCollection<BundleCapability>(result);
-                for (ResolverHook hook : m_hooks)
-                {
-                    try
-                    {
-                        Felix.m_secureAction
-                            .invokeResolverHookMatches(hook, req, shrinkable);
-                    }
-                    catch (Throwable th)
-                    {
-                        m_logger.log(Logger.LOG_WARNING, "Resolver hook exception.", th);
-                    }
-                }
-            }
-
-            return result;
-        }
-
-        private boolean filteredBySecurity(BundleRequirement req, BundleCapability cap)
-        {
-            if (System.getSecurityManager() != null)
-            {
-                BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
-
-                if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                        PackagePermission.EXPORTONLY)) ||
-                        !((reqRevision == null) ||
-                            ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                                new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                                cap.getRevision().getBundle(),PackagePermission.IMPORT))
-                        ))
-                    {
-                        if (reqRevision != cap.getRevision())
-                        {
-                            return true;
-                        }
-                    }
-                }
-                else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
-                {   if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
-                        !((reqRevision == null) ||
-                            ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                                new BundlePermission(reqRevision.getSymbolicName(), BundlePermission.REQUIRE))
-                        ))
-                    {
-                        return true;
-                    }
-                }
-                else if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-                {
-                    if (!((BundleProtectionDomain) reqRevision.getProtectionDomain())
-                        .impliesDirect(new BundlePermission(
-                            reqRevision.getSymbolicName(),
-                            BundlePermission.FRAGMENT))
-                    || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain())
-                        .impliesDirect(new BundlePermission(
-                            cap.getRevision().getSymbolicName(),
-                            BundlePermission.HOST)))
-                    {
-                        return true;
-                    }
-                }
-                else  if (!req.getNamespace().equals("osgi.ee"))
-                {
-                    if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new CapabilityPermission(req.getNamespace(), CapabilityPermission.PROVIDE))
-                        ||
-                        !((reqRevision == null) || ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                        new CapabilityPermission(req.getNamespace(), cap.getAttributes(), cap.getRevision().getBundle(), CapabilityPermission.REQUIRE))))
-                    {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        public void checkExecutionEnvironment(BundleRevision revision) throws ResolveException
-        {
-            String bundleExecEnvStr = (String)
-                ((BundleRevisionImpl) revision).getHeaders().get(
-                    Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
-            if (bundleExecEnvStr != null)
-            {
-                bundleExecEnvStr = bundleExecEnvStr.trim();
-
-                // If the bundle has specified an execution environment and the
-                // framework has an execution environment specified, then we must
-                // check for a match.
-                if (!bundleExecEnvStr.equals("")
-                    && (m_fwkExecEnvStr != null)
-                    && (m_fwkExecEnvStr.length() > 0))
-                {
-                    StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
-                    boolean found = false;
-                    while (tokens.hasMoreTokens() && !found)
-                    {
-                        if (m_fwkExecEnvSet.contains(tokens.nextToken().trim()))
-                        {
-                            found = true;
-                        }
-                    }
-                    if (!found)
-                    {
-                        throw new ResolveException(
-                            "Execution environment not supported: "
-                            + bundleExecEnvStr, revision, null);
-                    }
-                }
-            }
-        }
-
-        public void checkNativeLibraries(BundleRevision revision) throws ResolveException
-        {
-            // Next, try to resolve any native code, since the revision is
-            // not resolvable if its native code cannot be loaded.
-            List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
-            if (libs != null)
-            {
-                String msg = null;
-                // Verify that all native libraries exist in advance; this will
-                // throw an exception if the native library does not exist.
-                for (int libIdx = 0; (msg == null) && (libIdx < libs.size()); libIdx++)
-                {
-                    String entryName = libs.get(libIdx).getEntryName();
-                    if (entryName != null)
-                    {
-                        if (!((BundleRevisionImpl) revision).getContent().hasEntry(entryName))
-                        {
-                            msg = "Native library does not exist: " + entryName;
-                        }
-                    }
-                }
-                // If we have a zero-length native library array, then
-                // this means no native library class could be selected
-                // so we should fail to resolve.
-                if (libs.isEmpty())
-                {
-                    msg = "No matching native libraries found.";
-                }
-                if (msg != null)
-                {
-                    throw new ResolveException(msg, revision, null);
+                    capSet.addCapability(cap);
                 }
             }
         }
     }
 
-    //
-    // Utility methods.
-    //
+    private synchronized void deindexCapabilities(BundleRevision br)
+    {
+        // We only need be concerned with declared capabilities here,
+        // because resolved capabilities will be a subset, since fragment
+        // capabilities are not considered to be part of the host.
+        List<BundleCapability> caps = br.getDeclaredCapabilities(null);
+        if (caps != null)
+        {
+            for (BundleCapability cap : caps)
+            {
+                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+                if (capSet != null)
+                {
+                    capSet.removeCapability(cap);
+                }
+            }
+        }
+    }
+
+    private synchronized boolean isSelectedSingleton(BundleRevision br)
+    {
+        return m_selectedSingletons.contains(br);
+    }
+
+    private synchronized void selectSingletons()
+        throws BundleException
+    {
+        // First deindex any unresolved singletons to make sure
+        // there aren't any available from previous resolves.
+        // Also remove them from the fragment list, for the same
+        // reason.
+        m_selectedSingletons.clear();
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
+        {
+            for (BundleRevision singleton : entry.getValue())
+            {
+                if (singleton.getWiring() == null)
+                {
+                    deindexCapabilities(singleton);
+                    m_fragments.remove(singleton);
+                }
+            }
+        }
+
+        // If no resolver hooks, then use default singleton selection
+        // algorithm, otherwise defer to the resolver hooks.
+        if (m_hooks.isEmpty())
+        {
+            selectDefaultSingletons();
+        }
+        else
+        {
+            selectSingletonsUsingHooks();
+        }
+    }
+
+    /*
+     * Selects the singleton with the highest version from groupings
+     * based on the symbolic name. No selection is made if the group
+     * already has a resolved singleton.
+     */
+    private void selectDefaultSingletons()
+    {
+        // Now select the singletons available for this resolve operation.
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
+        {
+            selectSingleton(entry.getValue());
+        }
+    }
+
+    /*
+     * Groups singletons based on resolver hook filtering and then selects
+     * the singleton from each group with the highest version that is in
+     * the resolver hook whitelist. No selection is made if a group already
+     * has a resolved singleton in it.
+     */
+    private void selectSingletonsUsingHooks()
+        throws BundleException
+    {
+        // Convert singleton bundle revision map into a map using
+        // bundle capabilities instead, since this is what the resolver
+        // hooks require.
+        Map<BundleCapability, Collection<BundleCapability>> allCollisions
+            = new HashMap<BundleCapability, Collection<BundleCapability>>();
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
+        {
+            Collection<BundleCapability> bundleCaps =
+                new ArrayList<BundleCapability>();
+            for (BundleRevision br : entry.getValue())
+            {
+                List<BundleCapability> caps =
+                    br.getDeclaredCapabilities(BundleRevision.BUNDLE_NAMESPACE);
+                if (!caps.isEmpty())
+                {
+                    bundleCaps.add(caps.get(0));
+                }
+            }
+
+            for (BundleCapability bc : bundleCaps)
+            {
+                Collection<BundleCapability> capCopy =
+                    new ShrinkableCollection<BundleCapability>(
+                        new ArrayList<BundleCapability>(bundleCaps));
+                capCopy.remove(bc);
+                allCollisions.put(bc, capCopy);
+            }
+        }
+
+        // Invoke hooks to allow them to filter singleton collisions.
+        for (ResolverHook hook : m_hooks)
+        {
+            for (Entry<BundleCapability, Collection<BundleCapability>> entry
+                : allCollisions.entrySet())
+            {
+                try
+                {
+                    Felix.m_secureAction
+                        .invokeResolverHookSingleton(hook, entry.getKey(), entry.getValue());
+                }
+                catch (Throwable ex)
+                {
+                    throw new BundleException(
+                        "Resolver hook exception: " + ex.getMessage(),
+                        BundleException.REJECTED_BY_HOOK,
+                        ex);
+                }
+            }
+        }
+
+        // Create groups according to how the resolver hooks filtered the
+        // collisions.
+        List<List<BundleRevision>> groups = new ArrayList<List<BundleRevision>>();
+        while (!allCollisions.isEmpty())
+        {
+            BundleCapability target = allCollisions.entrySet().iterator().next().getKey();
+            groups.add(groupSingletons(allCollisions, target, new ArrayList<BundleRevision>()));
+        }
+
+        // Now select the singletons available for this resolve operation.
+        for (List<BundleRevision> group : groups)
+        {
+            selectSingleton(group);
+        }
+    }
+
+    private List<BundleRevision> groupSingletons(
+        Map<BundleCapability, Collection<BundleCapability>> allCollisions,
+        BundleCapability target, List<BundleRevision> group)
+    {
+        if (!group.contains(target.getRevision()))
+        {
+            // Add the target since it is implicitly part of the group.
+            group.add(target.getRevision());
+
+            // Recursively add the revisions of any singleton's in the
+            // target's collisions.
+            Collection<BundleCapability> collisions = allCollisions.remove(target);
+            for (BundleCapability collision : collisions)
+            {
+                groupSingletons(allCollisions, collision, group);
+            }
+
+            // Need to check the values of other collisions for this target
+            // and add those to the target's group too, since collisions are
+            // treated as two-way relationships. Repeat until there are no
+            // collision groups left that contain the target capability.
+            boolean repeat;
+            do
+            {
+                repeat = false;
+                for (Entry<BundleCapability, Collection<BundleCapability>> entry:
+                    allCollisions.entrySet())
+                {
+                    if (entry.getValue().contains(target))
+                    {
+                        repeat = true;
+                        groupSingletons(allCollisions, entry.getKey(), group);
+                        break;
+                    }
+                }
+            }
+            while (repeat);
+        }
+        return group;
+    }
+
+    /*
+     * Selects the highest bundle revision from the group that is
+     * in the resolver hook whitelist (if there are hooks). No
+     * selection is made if there is an already resolved singleton
+     * in the group, since it is already indexed.
+     */
+    private void selectSingleton(List<BundleRevision> singletons)
+    {
+        BundleRevision selected = null;
+        for (BundleRevision singleton : singletons)
+        {
+            // If a singleton is already resolved,
+            // then there is nothing to do.
+            if (singleton.getWiring() != null)
+            {
+                selected = null;
+                break;
+            }
+            // If this singleton is not in the whitelist, then it cannot
+            // be selected. If it is, in can only be selected if it has
+            // a higher version than the currently selected singleton, if
+            // there is one.
+            if (((m_whitelist == null) || m_whitelist.contains(singleton))
+                && ((selected == null)
+                    || (selected.getVersion().compareTo(singleton.getVersion()) > 0)))
+            {
+                selected = singleton;
+            }
+        }
+        if (selected != null)
+        {
+            // Record the selected singleton.
+            m_selectedSingletons.add(selected);
+            // Index its capabilities.
+            indexCapabilities(selected);
+            // If the selected singleton is a fragment, then
+            // add it to the list of fragments.
+            if (Util.isFragment(selected))
+            {
+                m_fragments.add(selected);
+            }
+        }
+    }
+
+    private synchronized Set<BundleRevision> getFragments()
+    {
+        Set<BundleRevision> fragments = new HashSet(m_fragments);
+        // Filter out any fragments that are not the current revision.
+        for (Iterator<BundleRevision> it = fragments.iterator(); it.hasNext(); )
+        {
+            BundleRevision fragment = it.next();
+            BundleRevision currentFragmentRevision =
+                fragment.getBundle().adapt(BundleRevision.class);
+            if (fragment != currentFragmentRevision)
+            {
+                it.remove();
+            }
+        }
+        return fragments;
+    }
+
+    void checkExecutionEnvironment(BundleRevision revision) throws ResolveException
+    {
+        String bundleExecEnvStr = (String)
+            ((BundleRevisionImpl) revision).getHeaders().get(
+                Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+        if (bundleExecEnvStr != null)
+        {
+            bundleExecEnvStr = bundleExecEnvStr.trim();
+
+            // If the bundle has specified an execution environment and the
+            // framework has an execution environment specified, then we must
+            // check for a match.
+            if (!bundleExecEnvStr.equals("")
+                && (m_fwkExecEnvStr != null)
+                && (m_fwkExecEnvStr.length() > 0))
+            {
+                StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
+                boolean found = false;
+                while (tokens.hasMoreTokens() && !found)
+                {
+                    if (m_fwkExecEnvSet.contains(tokens.nextToken().trim()))
+                    {
+                        found = true;
+                    }
+                }
+                if (!found)
+                {
+                    throw new ResolveException(
+                        "Execution environment not supported: "
+                        + bundleExecEnvStr, revision, null);
+                }
+            }
+        }
+    }
+
+    void checkNativeLibraries(BundleRevision revision) throws ResolveException
+    {
+        // Next, try to resolve any native code, since the revision is
+        // not resolvable if its native code cannot be loaded.
+        List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
+        if (libs != null)
+        {
+            String msg = null;
+            // Verify that all native libraries exist in advance; this will
+            // throw an exception if the native library does not exist.
+            for (int libIdx = 0; (msg == null) && (libIdx < libs.size()); libIdx++)
+            {
+                String entryName = libs.get(libIdx).getEntryName();
+                if (entryName != null)
+                {
+                    if (!((BundleRevisionImpl) revision).getContent().hasEntry(entryName))
+                    {
+                        msg = "Native library does not exist: " + entryName;
+                    }
+                }
+            }
+            // If we have a zero-length native library array, then
+            // this means no native library class could be selected
+            // so we should fail to resolve.
+            if (libs.isEmpty())
+            {
+                msg = "No matching native libraries found.";
+            }
+            if (msg != null)
+            {
+                throw new ResolveException(msg, revision, null);
+            }
+        }
+    }
+
+    private synchronized Set<BundleRevision> getUnresolvedRevisions()
+    {
+        Set<BundleRevision> unresolved = new HashSet<BundleRevision>();
+        for (BundleRevision revision : m_revisions)
+        {
+            if (revision.getWiring() == null)
+            {
+                unresolved.add(revision);
+            }
+        }
+        return unresolved;
+    }
+
+    private synchronized Map<BundleRevision, BundleWiring> getWirings()
+    {
+        Map<BundleRevision, BundleWiring> wirings = new HashMap<BundleRevision, BundleWiring>();
+
+        for (BundleRevision revision : m_revisions)
+        {
+            if (revision.getWiring() != null)
+            {
+                wirings.put(revision, revision.getWiring());
+            }
+        }
+        return wirings;
+    }
 
     /**
      * Updates the framework wide execution environment string and a cached Set of
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
index d244685..1d8722a 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -27,11 +27,8 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.TreeMap;
-import java.util.TreeSet;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.resolver.Resolver.ResolverState;
+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;
@@ -50,15 +47,14 @@
     public static final int OPTIONAL = 1;
     public static final int ON_DEMAND = 2;
 
-    // Set of all mandatory bundle revisions.
     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, SortedSet<BundleCapability>> m_candidateMap;
+    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, HostBundleRevision> m_allWrappedHosts;
+    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;
 
@@ -75,8 +71,8 @@
     private Candidates(
         Set<BundleRevision> mandatoryRevisions,
         Map<BundleCapability, Set<BundleRequirement>> dependentMap,
-        Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap,
-        Map<BundleRevision, HostBundleRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
+        Map<BundleRequirement, List<BundleCapability>> candidateMap,
+        Map<BundleRevision, WrappedRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
         boolean fragmentsPresent)
     {
         m_mandatoryRevisions = mandatoryRevisions;
@@ -94,8 +90,8 @@
     {
         m_mandatoryRevisions = new HashSet<BundleRevision>();
         m_dependentMap = new HashMap<BundleCapability, Set<BundleRequirement>>();
-        m_candidateMap = new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
-        m_allWrappedHosts = new HashMap<BundleRevision, HostBundleRevision>();
+        m_candidateMap = new HashMap<BundleRequirement, List<BundleCapability>>();
+        m_allWrappedHosts = new HashMap<BundleRevision, WrappedRevision>();
         m_populateResultCache = new HashMap<BundleRevision, Object>();
     }
 
@@ -116,7 +112,7 @@
      * @param resolution indicates the resolution type.
      */
     public final void populate(
-        ResolverState state, BundleRevision revision, int resolution)
+        ResolveContext rc, BundleRevision revision, int resolution)
     {
         // Get the current result cache value, to make sure the revision
         // hasn't already been populated.
@@ -146,7 +142,7 @@
         // However, for on-demand fragments only populate if their host
         // is already populated.
         if ((resolution != ON_DEMAND)
-            || (isFragment && populateFragmentOndemand(state, revision)))
+            || (isFragment && populateFragmentOndemand(rc, revision)))
         {
             if (resolution == MANDATORY)
             {
@@ -155,7 +151,7 @@
             try
             {
                 // Try to populate candidates for the optional revision.
-                populateRevision(state, revision);
+                populateRevision(rc, revision);
             }
             catch (ResolveException ex)
             {
@@ -174,7 +170,7 @@
      * @param revision the revision whose candidates should be populated.
      */
 // TODO: FELIX3 - Modify to not be recursive.
-    private void populateRevision(ResolverState state, BundleRevision revision)
+    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:
@@ -196,7 +192,7 @@
 
         // Keeps track of the candidates we've already calculated for the
         // current revision's requirements.
-        Map<BundleRequirement, SortedSet<BundleCapability>> localCandidateMap = null;
+        Map<BundleRequirement, List<BundleCapability>> localCandidateMap = null;
 
         // Keeps track of the current revision's requirements for which we
         // haven't yet found candidates.
@@ -234,10 +230,10 @@
         if ((remainingReqs == null) && (localCandidateMap == null))
         {
             // Verify that any required execution environment is satisfied.
-            state.checkExecutionEnvironment(revision);
+            ((ResolveContextImpl) rc).checkExecutionEnvironment(revision);
 
             // Verify that any native libraries match the current platform.
-            state.checkNativeLibraries(revision);
+            ((ResolveContextImpl) rc).checkNativeLibraries(revision);
 
             // Record cycle count.
             cycleCount = new Integer(0);
@@ -263,7 +259,7 @@
 
             // Ignore non-effective and dynamic requirements.
             String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-            if (!state.isEffective(req)
+            if (!rc.isEffective(req)
                 || ((resolution != null)
                     && resolution.equals(FelixConstants.RESOLUTION_DYNAMIC)))
             {
@@ -272,9 +268,8 @@
 
             // Process the candidates, removing any candidates that
             // cannot resolve.
-            SortedSet<BundleCapability> candidates =
-                state.getCandidates((BundleRequirementImpl) req, true);
-            ResolveException rethrow = processCandidates(state, revision, candidates);
+            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.
@@ -324,7 +319,7 @@
         }
     }
 
-    private boolean populateFragmentOndemand(ResolverState state, BundleRevision revision)
+    private boolean populateFragmentOndemand(ResolveContext rc, BundleRevision revision)
         throws ResolveException
     {
         // Create a modifiable list of the revision's requirements.
@@ -344,8 +339,7 @@
             }
         }
         // Get candidates hosts and keep any that have been populated.
-        SortedSet<BundleCapability> hosts =
-            state.getCandidates((BundleRequirementImpl) hostReq, false);
+        List<BundleCapability> hosts = rc.findProviders(hostReq, false);
         for (Iterator<BundleCapability> it = hosts.iterator(); it.hasNext(); )
         {
             BundleCapability host = it.next();
@@ -364,16 +358,16 @@
         // some other checks and prepopulate the result cache with
         // the work we've done so far.
         // Verify that any required execution environment is satisfied.
-        state.checkExecutionEnvironment(revision);
+        ((ResolveContextImpl) rc).checkExecutionEnvironment(revision);
         // Verify that any native libraries match the current platform.
-        state.checkNativeLibraries(revision);
+        ((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, SortedSet<BundleCapability>> localCandidateMap =
-            new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
+        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
@@ -385,8 +379,8 @@
     }
 
     public void populateDynamic(
-        ResolverState state, BundleRevision revision,
-        BundleRequirement req, SortedSet<BundleCapability> candidates)
+        ResolveContext rc, BundleRevision revision,
+        BundleRequirement req, List<BundleCapability> candidates)
     {
         // Record the revision associated with the dynamic require
         // as a mandatory revision.
@@ -397,7 +391,7 @@
 
         // Process the candidates, removing any candidates that
         // cannot resolve.
-        ResolveException rethrow = processCandidates(state, revision, candidates);
+        ResolveException rethrow = processCandidates(rc, revision, candidates);
 
         if (candidates.isEmpty())
         {
@@ -423,9 +417,9 @@
      * @return a resolve exception to be re-thrown, if any, or null.
      */
     private ResolveException processCandidates(
-        ResolverState state,
+        ResolveContext rc,
         BundleRevision revision,
-        SortedSet<BundleCapability> candidates)
+        List<BundleCapability> candidates)
     {
         // Get satisfying candidates and populate their candidates if necessary.
         ResolveException rethrow = null;
@@ -466,7 +460,7 @@
             {
                 try
                 {
-                    populateRevision(state, candCap.getRevision());
+                    populateRevision(rc, candCap.getRevision());
                 }
                 catch (ResolveException ex)
                 {
@@ -505,8 +499,19 @@
                         {
                             // Note that we can just add this as a candidate
                             // directly, since we know it is already resolved.
-                            candidates.add(
-                                new HostedCapability(
+                            // 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));
                         }
@@ -540,7 +545,7 @@
      * @param req the requirement to add.
      * @param candidates the candidates matching the requirement.
     **/
-    private void add(BundleRequirement req, SortedSet<BundleCapability> candidates)
+    private void add(BundleRequirement req, List<BundleCapability> candidates)
     {
         if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
         {
@@ -557,9 +562,9 @@
      * be further modified by the caller.
      * @param candidates the bulk requirements and candidates to add.
     **/
-    private void add(Map<BundleRequirement, SortedSet<BundleCapability>> candidates)
+    private void add(Map<BundleRequirement, List<BundleCapability>> candidates)
     {
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry : candidates.entrySet())
+        for (Entry<BundleRequirement, List<BundleCapability>> entry : candidates.entrySet())
         {
             add(entry.getKey(), entry.getValue());
         }
@@ -583,7 +588,7 @@
      * @param req the requirement whose candidates are desired.
      * @return the matching candidates or null.
     **/
-    public SortedSet<BundleCapability> getCandidates(BundleRequirement req)
+    public List<BundleCapability> getCandidates(BundleRequirement req)
     {
         return m_candidateMap.get(req);
     }
@@ -604,7 +609,7 @@
      * @throws ResolveException if the removal of any unselected fragments result
      *         in the root module being unable to resolve.
     **/
-    public void prepare()
+    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
@@ -632,7 +637,7 @@
         //      with host's attached fragment capabilities.
 
         // Steps 1 and 2
-        List<HostBundleRevision> hostRevisions = new ArrayList<HostBundleRevision>();
+        List<WrappedRevision> hostRevisions = new ArrayList<WrappedRevision>();
         List<BundleRevision> unselectedFragments = new ArrayList<BundleRevision>();
         for (Entry<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
             hostEntry : hostFragments.entrySet())
@@ -667,7 +672,7 @@
                         else
                         {
                             m_dependentMap.get(hostCap).remove(hostReq);
-                            SortedSet<BundleCapability> hosts = m_candidateMap.get(hostReq);
+                            List<BundleCapability> hosts = m_candidateMap.get(hostReq);
                             hosts.remove(hostCap);
                             if (hosts.isEmpty())
                             {
@@ -679,8 +684,8 @@
             }
 
             // Step 2
-            HostBundleRevision wrappedHost =
-                new HostBundleRevision(hostCap.getRevision(), selectedFragments);
+            WrappedRevision wrappedHost =
+                new WrappedRevision(hostCap.getRevision(), selectedFragments);
             hostRevisions.add(wrappedHost);
             m_allWrappedHosts.put(hostCap.getRevision(), wrappedHost);
         }
@@ -694,7 +699,7 @@
         }
 
         // Step 4
-        for (HostBundleRevision hostRevision : hostRevisions)
+        for (WrappedRevision hostRevision : hostRevisions)
         {
             // Replaces capabilities from fragments with the capabilities
             // from the merged host.
@@ -704,8 +709,7 @@
                 // really be attached to the original host, not the wrapper.
                 if (!c.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
                 {
-                    BundleCapability origCap =
-                        ((HostedCapability) c).getOriginalCapability();
+                    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
@@ -717,9 +721,63 @@
                         m_dependentMap.put(c, dependents);
                         for (BundleRequirement r : dependents)
                         {
-                            Set<BundleCapability> cands = m_candidateMap.get(r);
-                            cands.remove(origCap);
-                            cands.add(c);
+                            // 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);
+                            }
                         }
                     }
                 }
@@ -729,11 +787,11 @@
             for (BundleRequirement r : hostRevision.getDeclaredRequirements(null))
             {
                 BundleRequirement origReq =
-                    ((HostedRequirement) r).getOriginalRequirement();
-                SortedSet<BundleCapability> cands = m_candidateMap.get(origReq);
+                    ((WrappedRequirement) r).getOriginalRequirement();
+                List<BundleCapability> cands = m_candidateMap.get(origReq);
                 if (cands != null)
                 {
-                    m_candidateMap.put(r, new TreeSet<BundleCapability>(cands));
+                    m_candidateMap.put(r, new ArrayList<BundleCapability>(cands));
                     for (BundleCapability cand : cands)
                     {
                         Set<BundleRequirement> dependents = m_dependentMap.get(cand);
@@ -766,11 +824,10 @@
         Map<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
             hostFragments = new HashMap<BundleCapability,
                 Map<String, Map<Version, List<BundleRequirement>>>>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
-            : m_candidateMap.entrySet())
+        for (Entry<BundleRequirement, List<BundleCapability>> entry : m_candidateMap.entrySet())
         {
             BundleRequirement req = entry.getKey();
-            SortedSet<BundleCapability> caps = entry.getValue();
+            List<BundleCapability> caps = entry.getValue();
             for (BundleCapability cap : caps)
             {
                 // Record the requirement as dependent on the capability.
@@ -871,7 +928,7 @@
     {
         boolean isFragment = req.getNamespace().equals(BundleRevision.HOST_NAMESPACE);
 
-        SortedSet<BundleCapability> candidates = m_candidateMap.remove(req);
+        List<BundleCapability> candidates = m_candidateMap.remove(req);
         if (candidates != null)
         {
             for (BundleCapability cap : candidates)
@@ -902,7 +959,7 @@
         {
             for (BundleRequirement r : dependents)
             {
-                SortedSet<BundleCapability> candidates = m_candidateMap.get(r);
+                List<BundleCapability> candidates = m_candidateMap.get(r);
                 candidates.remove(c);
                 if (candidates.isEmpty())
                 {
@@ -935,13 +992,13 @@
             dependentMap.put(entry.getKey(), dependents);
         }
 
-        Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap =
-            new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
+        Map<BundleRequirement, List<BundleCapability>> candidateMap =
+            new HashMap<BundleRequirement, List<BundleCapability>>();
+        for (Entry<BundleRequirement, List<BundleCapability>> entry
             : m_candidateMap.entrySet())
         {
-            SortedSet<BundleCapability> candidates =
-                new TreeSet<BundleCapability>(entry.getValue());
+            List<BundleCapability> candidates =
+                new ArrayList<BundleCapability>(entry.getValue());
             candidateMap.put(entry.getKey(), candidates);
         }
 
@@ -954,7 +1011,7 @@
     {
         // Create set of all revisions from requirements.
         Set<BundleRevision> revisions = new HashSet<BundleRevision>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
+        for (Entry<BundleRequirement, List<BundleCapability>> entry
             : m_candidateMap.entrySet())
         {
             revisions.add(entry.getKey().getRevision());
@@ -970,7 +1027,7 @@
                 : br.getDeclaredRequirements(null);
             for (BundleRequirement req : reqs)
             {
-                Set<BundleCapability> candidates = m_candidateMap.get(req);
+                List<BundleCapability> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
@@ -981,7 +1038,7 @@
                 : Util.getDynamicRequirements(br.getDeclaredRequirements(null));
             for (BundleRequirement req : reqs)
             {
-                Set<BundleCapability> candidates = m_candidateMap.get(req);
+                List<BundleCapability> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
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
index dbdad1c..fc45301 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
@@ -1,122 +1,26 @@
 /*
- * 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
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * 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
  *
- * 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.
+ *      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;
 
-public class HostedCapability extends BundleCapabilityImpl
-{
-    private final BundleRevision m_host;
-    private final BundleCapabilityImpl m_cap;
+public interface HostedCapability extends BundleCapability {
 
-    public HostedCapability(BundleRevision host, BundleCapabilityImpl cap)
-    {
-        super(host, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
-        m_host = host;
-        m_cap = cap;
-    }
+	BundleRevision getRevision();
 
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (obj == null)
-        {
-            return false;
-        }
-        if (getClass() != obj.getClass())
-        {
-            return false;
-        }
-        final HostedCapability other = (HostedCapability) 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 BundleCapabilityImpl getOriginalCapability()
-    {
-        return m_cap;
-    }
-
-    @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
+	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
new file mode 100644
index 0000000..2af0696
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java
@@ -0,0 +1,52 @@
+/*
+ * 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/Resolver.java b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
index eabfdd1..107e4a7 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -28,21 +28,7 @@
 
 public interface Resolver
 {
+    Map<BundleRevision, List<ResolverWire>> resolve(ResolveContext rc);
     Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state,
-        Set<BundleRevision> mandatoryRevisions,
-        Set<BundleRevision> optionalRevisions,
-        Set<BundleRevision> ondemandFragments);
-    Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state, BundleRevision revision, String pkgName,
-        Set<BundleRevision> ondemandFragments);
-
-    public static interface ResolverState
-    {
-        boolean isEffective(BundleRequirement req);
-        SortedSet<BundleCapability> getCandidates(
-            BundleRequirement req, boolean obeyMandatory);
-        void checkExecutionEnvironment(BundleRevision revision) throws ResolveException;
-        void checkNativeLibraries(BundleRevision revision) throws ResolveException;
-    }
+        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
index 56203b3..8f1fabc 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -19,6 +19,7 @@
 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;
@@ -30,6 +31,7 @@
 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;
@@ -57,17 +59,17 @@
         m_logger = logger;
     }
 
-    public Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state,
-        Set<BundleRevision> mandatoryRevisions,
-        Set<BundleRevision> optionalRevisions,
-        Set<BundleRevision> ondemandFragments)
+    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
         {
@@ -86,7 +88,7 @@
                     BundleRevision br = it.next();
                     if (Util.isFragment(br) || (br.getWiring() == null))
                     {
-                        allCandidates.populate(state, br, Candidates.MANDATORY);
+                        allCandidates.populate(rc, br, Candidates.MANDATORY);
                     }
                     else
                     {
@@ -101,7 +103,7 @@
                     boolean isFragment = Util.isFragment(br);
                     if (isFragment || (br.getWiring() == null))
                     {
-                        allCandidates.populate(state, br, Candidates.OPTIONAL);
+                        allCandidates.populate(rc, br, Candidates.OPTIONAL);
                     }
                 }
 
@@ -112,12 +114,12 @@
                     boolean isFragment = Util.isFragment(br);
                     if (isFragment)
                     {
-                        allCandidates.populate(state, br, Candidates.ON_DEMAND);
+                        allCandidates.populate(rc, br, Candidates.ON_DEMAND);
                     }
                 }
 
                 // Merge any fragments into hosts.
-                allCandidates.prepare();
+                allCandidates.prepare(rc);
 
                 // Create a combined list of populated revisions; for
                 // optional revisions. We do not need to consider ondemand
@@ -207,11 +209,11 @@
                 if (rethrow != null)
                 {
                     BundleRevision faultyRevision =
-                        getActualBundleRevision(rethrow.getRevision());
-                    if (rethrow.getRequirement() instanceof HostedRequirement)
+                        getDeclaringBundleRevision(rethrow.getRevision());
+                    if (rethrow.getRequirement() instanceof WrappedRequirement)
                     {
                         faultyRevision =
-                            ((HostedRequirement) rethrow.getRequirement())
+                            ((WrappedRequirement) rethrow.getRequirement())
                                 .getOriginalRequirement().getRevision();
                     }
                     if (optionalRevisions.remove(faultyRevision))
@@ -267,8 +269,7 @@
     }
 
     public Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state, BundleRevision revision, String pkgName,
-        Set<BundleRevision> ondemandFragments)
+        ResolveContext rc, BundleRevision revision, String pkgName)
     {
         // We can only create a dynamic import if the following
         // conditions are met:
@@ -280,11 +281,16 @@
         // The following call checks all of these conditions and returns
         // the associated dynamic import and matching capabilities.
         Candidates allCandidates =
-            getDynamicImportCandidates(state, revision, pkgName);
+            getDynamicImportCandidates(rc, revision, pkgName);
         if (allCandidates != null)
         {
-            Map<BundleRevision, List<ResolverWire>> wireMap = new HashMap<BundleRevision, List<ResolverWire>>();
-            Map<BundleRevision, Packages> revisionPkgMap = new HashMap<BundleRevision, Packages>();
+            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
@@ -298,12 +304,12 @@
                     {
                         if (Util.isFragment(br))
                         {
-                            allCandidates.populate(state, br, Candidates.ON_DEMAND);
+                            allCandidates.populate(rc, br, Candidates.ON_DEMAND);
                         }
                     }
 
                     // Merge any fragments into hosts.
-                    allCandidates.prepare();
+                    allCandidates.prepare(rc);
 
                     // Record the initial candidate permutation.
                     m_usesPermutations.add(allCandidates);
@@ -355,11 +361,11 @@
                     if (rethrow != null)
                     {
                         BundleRevision faultyRevision =
-                            getActualBundleRevision(rethrow.getRevision());
-                        if (rethrow.getRequirement() instanceof HostedRequirement)
+                            getDeclaringBundleRevision(rethrow.getRevision());
+                        if (rethrow.getRequirement() instanceof WrappedRequirement)
                         {
                             faultyRevision =
-                                ((HostedRequirement) rethrow.getRequirement())
+                                ((WrappedRequirement) rethrow.getRequirement())
                                     .getOriginalRequirement().getRevision();
                         }
                         if (ondemandFragments.remove(faultyRevision))
@@ -394,7 +400,7 @@
     }
 
     private static Candidates getDynamicImportCandidates(
-        ResolverState state, BundleRevision revision, String pkgName)
+        ResolveContext rc, BundleRevision revision, String pkgName)
     {
         // Unresolved revisions cannot dynamically import, nor can the default
         // package be dynamically imported.
@@ -438,7 +444,7 @@
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        SortedSet<BundleCapability> candidates = state.getCandidates(req, false);
+        List<BundleCapability> candidates = rc.findProviders(req, false);
 
         // Try to find a dynamic requirement that matches the capabilities.
         BundleRequirementImpl dynReq = null;
@@ -484,7 +490,7 @@
         if (candidates.size() > 0)
         {
             allCandidates = new Candidates();
-            allCandidates.populateDynamic(state, revision, dynReq, candidates);
+            allCandidates.populateDynamic(rc, revision, dynReq, candidates);
         }
 
         return allCandidates;
@@ -523,7 +529,7 @@
                     || ((r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE) != null)
                         && r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE).equals("dynamic")))
                 {
-                    r = new HostedRequirement(
+                    r = new WrappedRequirement(
                         wire.getRequirerWiring().getRevision(),
                         (BundleRequirementImpl) r);
                 }
@@ -532,7 +538,7 @@
                 BundleCapability c = wire.getCapability();
                 if (!c.getRevision().equals(wire.getProviderWiring().getRevision()))
                 {
-                    c = new HostedCapability(
+                    c = new WrappedCapability(
                         wire.getProviderWiring().getRevision(),
                         (BundleCapabilityImpl) c);
                 }
@@ -547,15 +553,15 @@
                 : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
             {
                 // Get the candidates for the current requirement.
-                SortedSet<BundleCapability> candCaps =
-                    allCandidates.getCandidates((BundleRequirementImpl) req);
+                List<BundleCapability> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
                     continue;
                 }
 
-                BundleCapability cap = candCaps.iterator().next();
+                // Grab first (i.e., highest priority) candidate.
+                BundleCapability cap = candCaps.get(0);
                 reqs.add(req);
                 caps.add(cap);
                 isDynamicImporting = true;
@@ -573,15 +579,15 @@
                     || !resolution.equals(FelixConstants.RESOLUTION_DYNAMIC))
                 {
                     // Get the candidates for the current requirement.
-                    SortedSet<BundleCapability> candCaps =
-                        allCandidates.getCandidates((BundleRequirementImpl) req);
+                    List<BundleCapability> candCaps = allCandidates.getCandidates(req);
                     // Optional requirements may not have any candidates.
                     if (candCaps == null)
                     {
                         continue;
                     }
 
-                    BundleCapability cap = candCaps.iterator().next();
+                    // Grab first (i.e., highest priority) candidate.
+                    BundleCapability cap = candCaps.get(0);
                     reqs.add(req);
                     caps.add(cap);
                 }
@@ -974,6 +980,7 @@
             }
         }
 
+        // Check if there are any uses conflicts with exported packages.
         for (Entry<String, Blame> entry : pkgs.m_exportedPkgs.entrySet())
         {
             String pkgName = entry.getKey();
@@ -1026,14 +1033,12 @@
                         // 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.
-                        SortedSet<BundleCapability> candidates =
-                            permutation.getCandidates(req);
+                        List<BundleCapability> candidates = permutation.getCandidates(req);
                         if ((candidates != null) && (candidates.size() > 1))
                         {
                             mutated.add(req);
-                            Iterator it = candidates.iterator();
-                            it.next();
-                            it.remove();
+                            // Remove the conflicting candidate.
+                            candidates.remove(0);
                             // Continue with the next uses constraint.
                             break;
                         }
@@ -1115,14 +1120,12 @@
                             // 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.
-                            SortedSet<BundleCapability> candidates =
-                                permutation.getCandidates(req);
+                            List<BundleCapability> candidates = permutation.getCandidates(req);
                             if ((candidates != null) && (candidates.size() > 1))
                             {
                                 mutated.add(req);
-                                Iterator it = candidates.iterator();
-                                it.next();
-                                it.remove();
+                                // Remove the conflicting candidate.
+                                candidates.remove(0);
                                 // Continue with the next uses constraint.
                                 break;
                             }
@@ -1207,14 +1210,12 @@
     private static void permutate(
         Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
     {
-        SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+        List<BundleCapability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             Candidates perm = allCandidates.copy();
             candidates = perm.getCandidates(req);
-            Iterator it = candidates.iterator();
-            it.next();
-            it.remove();
+            candidates.remove(0);
             permutations.add(perm);
         }
     }
@@ -1222,7 +1223,7 @@
     private static void permutateIfNeeded(
         Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
     {
-        SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+        List<BundleCapability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             // Check existing permutations to make sure we haven't
@@ -1234,8 +1235,8 @@
             boolean permutated = false;
             for (Candidates existingPerm : permutations)
             {
-                Set<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
-                if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
+                List<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
+                if (!existingPermCands.get(0).equals(candidates.get(0)))
                 {
                     permutated = true;
                 }
@@ -1273,7 +1274,7 @@
             {
                 if (!cap.getRevision().equals(revision))
                 {
-                    cap = new HostedCapability(revision, (BundleCapabilityImpl) cap);
+                    cap = new WrappedCapability(revision, (BundleCapabilityImpl) cap);
                 }
                 exports.put(
                     (String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
@@ -1293,11 +1294,10 @@
                 {
                     if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                     {
-                        Set<BundleCapability> cands =
-                            allCandidates.getCandidates((BundleRequirementImpl) req);
+                        List<BundleCapability> cands = allCandidates.getCandidates(req);
                         if ((cands != null) && !cands.isEmpty())
                         {
-                            String pkgName = (String) cands.iterator().next()
+                            String pkgName = (String) cands.get(0)
                                 .getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
                             exports.remove(pkgName);
                         }
@@ -1401,7 +1401,7 @@
                     if (!cap.getRevision().equals(sourceCap.getRevision()))
                     {
                         sources.add(
-                            new HostedCapability(cap.getRevision(), (BundleCapabilityImpl) sourceCap));
+                            new WrappedCapability(cap.getRevision(), (BundleCapabilityImpl) sourceCap));
                     }
                     else
                     {
@@ -1425,29 +1425,29 @@
         return sources;
     }
 
-    private static BundleRevision getActualBundleRevision(BundleRevision br)
+    private static BundleRevision getDeclaringBundleRevision(BundleRevision br)
     {
-        if (br instanceof HostBundleRevision)
+        if (br instanceof WrappedRevision)
         {
-            return ((HostBundleRevision) br).getHost();
+            return ((WrappedRevision) br).getHost();
         }
         return br;
     }
 
-    private static BundleCapability getActualCapability(BundleCapability c)
+    private static BundleCapability getDeclaredCapability(BundleCapability c)
     {
         if (c instanceof HostedCapability)
         {
-            return ((HostedCapability) c).getOriginalCapability();
+            return ((HostedCapability) c).getDeclaredCapability();
         }
         return c;
     }
 
-    private static BundleRequirement getActualRequirement(BundleRequirement r)
+    private static BundleRequirement getDeclaredRequirement(BundleRequirement r)
     {
-        if (r instanceof HostedRequirement)
+        if (r instanceof WrappedRequirement)
         {
-            return ((HostedRequirement) r).getOriginalRequirement();
+            return ((WrappedRequirement) r).getOriginalRequirement();
         }
         return r;
     }
@@ -1457,7 +1457,7 @@
         Map<BundleRevision, List<ResolverWire>> wireMap,
         Candidates allCandidates)
     {
-        BundleRevision unwrappedRevision = getActualBundleRevision(revision);
+        BundleRevision unwrappedRevision = getDeclaringBundleRevision(revision);
         if ((unwrappedRevision.getWiring() == null)
             && !wireMap.containsKey(unwrappedRevision))
         {
@@ -1469,10 +1469,10 @@
 
             for (BundleRequirement req : revision.getDeclaredRequirements(null))
             {
-                SortedSet<BundleCapability> cands = allCandidates.getCandidates(req);
+                List<BundleCapability> cands = allCandidates.getCandidates(req);
                 if ((cands != null) && (cands.size() > 0))
                 {
-                    BundleCapability cand = cands.iterator().next();
+                    BundleCapability cand = cands.get(0);
                     // Ignore revisions that import themselves.
                     if (!revision.equals(cand.getRevision()))
                     {
@@ -1484,9 +1484,9 @@
                         Packages candPkgs = revisionPkgMap.get(cand.getRevision());
                         ResolverWire wire = new ResolverWireImpl(
                             unwrappedRevision,
-                            getActualRequirement(req),
-                            getActualBundleRevision(cand.getRevision()),
-                            getActualCapability(cand));
+                            getDeclaredRequirement(req),
+                            getDeclaringBundleRevision(cand.getRevision()),
+                            getDeclaredCapability(cand));
                         if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                         {
                             packageWires.add(wire);
@@ -1509,9 +1509,9 @@
             wireMap.put(unwrappedRevision, packageWires);
 
             // Add host wire for any fragments.
-            if (revision instanceof HostBundleRevision)
+            if (revision instanceof WrappedRevision)
             {
-                List<BundleRevision> fragments = ((HostBundleRevision) revision).getFragments();
+                List<BundleRevision> fragments = ((WrappedRevision) revision).getFragments();
                 for (BundleRevision fragment : fragments)
                 {
                     List<ResolverWire> hostWires = wireMap.get(fragment);
@@ -1522,7 +1522,7 @@
                     }
                     hostWires.add(
                         new ResolverWireImpl(
-                            getActualBundleRevision(fragment),
+                            getDeclaringBundleRevision(fragment),
                             fragment.getDeclaredRequirements(
                                 BundleRevision.HOST_NAMESPACE).get(0),
                             unwrappedRevision,
@@ -1549,8 +1549,7 @@
             : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
         {
             // Get the candidates for the current dynamic requirement.
-            SortedSet<BundleCapability> candCaps =
-                allCandidates.getCandidates((BundleRequirementImpl) req);
+            List<BundleCapability> candCaps = allCandidates.getCandidates(req);
             // Optional requirements may not have any candidates.
             if ((candCaps == null) || candCaps.isEmpty())
             {
@@ -1559,7 +1558,7 @@
 
             // Record the dynamic requirement.
             dynReq = req;
-            dynCand = candCaps.first();
+            dynCand = candCaps.get(0);
 
             // Can only dynamically import one at a time, so break
             // out of the loop after the first.
@@ -1580,8 +1579,8 @@
                 new ResolverWireImpl(
                     revision,
                     dynReq,
-                    getActualBundleRevision(dynCand.getRevision()),
-                    getActualCapability(dynCand)));
+                    getDeclaringBundleRevision(dynCand.getRevision()),
+                    getDeclaredCapability(dynCand)));
         }
 
         wireMap.put(revision, packageWires);
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
new file mode 100644
index 0000000..e64b559
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ShadowList.java
@@ -0,0 +1,157 @@
+/*
+ * 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
new file mode 100644
index 0000000..5e31d03
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
@@ -0,0 +1,60 @@
+/*
+ * 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 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
new file mode 100644
index 0000000..7a21ec4
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+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 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/HostedRequirement.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
similarity index 93%
rename from framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
rename to framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
index 58dadce..c0d15e0 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
@@ -23,12 +23,12 @@
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.wiring.BundleRevision;
 
-public class HostedRequirement extends BundleRequirementImpl
+public class WrappedRequirement extends BundleRequirementImpl
 {
     private final BundleRevision m_host;
     private final BundleRequirementImpl m_req;
 
-    public HostedRequirement(BundleRevision host, BundleRequirementImpl req)
+    public WrappedRequirement(BundleRevision host, BundleRequirementImpl req)
     {
         super(host, req.getNamespace(), req.getDirectives(), req.getAttributes());
         m_host = host;
@@ -46,7 +46,7 @@
         {
             return false;
         }
-        final HostedRequirement other = (HostedRequirement) obj;
+        final WrappedRequirement other = (WrappedRequirement) obj;
         if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
         {
             return false;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
similarity index 89%
rename from framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
rename to framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
index 3f052bb..81c41ee 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
@@ -30,14 +30,14 @@
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWiring;
 
-class HostBundleRevision implements BundleRevision
+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 HostBundleRevision(BundleRevision host, List<BundleRevision> fragments)
+    public WrappedRevision(BundleRevision host, List<BundleRevision> fragments)
     {
         m_host = host;
         m_fragments = fragments;
@@ -72,7 +72,7 @@
             // Wrap host capabilities.
             for (BundleCapability cap : m_host.getDeclaredCapabilities(null))
             {
-                caps.add(new HostedCapability(this, (BundleCapabilityImpl) cap));
+                caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
             }
 
             // Wrap fragment capabilities.
@@ -84,7 +84,7 @@
                     {
 // 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 HostedCapability(this, (BundleCapabilityImpl) cap));
+                        caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
                     }
                 }
             }
@@ -102,7 +102,7 @@
             // Wrap host requirements.
             for (BundleRequirement req : m_host.getDeclaredRequirements(null))
             {
-                reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
+                reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
             }
 
             // Wrap fragment requirements.
@@ -114,7 +114,7 @@
                     {
                         if (!req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
                         {
-                            reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
+                            reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
                         }
                     }
                 }
