diff --git a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java b/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
index 8f89e6e..a158306 100644
--- a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
+++ b/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
@@ -19,53 +19,105 @@
 package org.apache.felix.framework;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import org.apache.felix.framework.searchpolicy.ResolveException;
-import org.apache.felix.framework.searchpolicy.Resolver;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.resolver.CandidateComparator;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.Resolver;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.VersionRange;
-import org.apache.felix.framework.util.manifestparser.R4Attribute;
-import org.apache.felix.framework.util.manifestparser.R4Directive;
-import org.apache.felix.framework.util.manifestparser.Requirement;
-import org.apache.felix.moduleloader.ICapability;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
-import org.apache.felix.moduleloader.IWire;
 import org.osgi.framework.BundlePermission;
 import org.osgi.framework.Constants;
-import org.osgi.framework.PackagePermission;
 import org.osgi.framework.Version;
 
 public class FelixResolverState implements Resolver.ResolverState
 {
     private final Logger m_logger;
     // List of all modules.
-    private final List m_moduleList = new ArrayList();
-    // Map of fragment symbolic names to list of fragment modules sorted by version.
-    private final Map m_fragmentMap = new HashMap();
-    // Maps a package name to a list of exporting capabilities.
-    private final Map m_unresolvedPkgIndex = new HashMap();
-    // Maps a package name to a list of exporting capabilities.
-    private final Map m_resolvedPkgIndex = new HashMap();
-    // Maps a module to a list of capabilities.
-    private final Map m_resolvedCapMap = new HashMap();
+    private final List<Module> m_modules;
+    // Capability set for modules.
+    private final CapabilitySet m_modCapSet;
+    // Capability set for packages.
+    private final CapabilitySet m_pkgCapSet;
+    // Capability set for hosts.
+    private final CapabilitySet m_hostCapSet;
+    // Maps fragment symbolic names to list of fragment modules sorted by version.
+    private final Map<String, List<Module>> m_fragmentMap = new HashMap();
+    // Maps singleton symbolic names to list of modules sorted by version.
+    private final Map<String, List<Module>> m_singletons = new HashMap();
 
     public FelixResolverState(Logger logger)
     {
         m_logger = logger;
+        m_modules = new ArrayList<Module>();
+
+        List indices = new ArrayList();
+        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+        m_modCapSet = new CapabilitySet(indices);
+
+        indices = new ArrayList();
+        indices.add(Capability.PACKAGE_ATTR);
+        m_pkgCapSet = new CapabilitySet(indices);
+
+        indices = new ArrayList();
+        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+        m_hostCapSet = new CapabilitySet(indices);
     }
 
-    public synchronized void addModule(IModule module)
+    public synchronized void addModule(Module module)
     {
-        if (Util.isFragment(module))
+        if (isSingleton(module))
         {
-            addFragment(module);
+            // Find the currently selected singleton, which is either the
+            // highest version or the resolved one.
+            List<Module> modules = m_singletons.get(module.getSymbolicName());
+            // Get the highest version.
+            Module current = ((modules != null) && !modules.isEmpty()) ? modules.get(0) : null;
+            // Now check to see if there is a resolved one instead.
+            for (int i = 0; (modules != null) && (i < modules.size()); i++)
+            {
+                if (modules.get(i).isResolved())
+                {
+                    current = modules.get(i);
+                }
+            }
+
+            // Index the new singleton.
+            Module highest = indexModule(m_singletons, module);
+            // If the currently selected singleton is not resolved and
+            // the newly added singleton is a higher version, then select
+            // it instead.
+            if ((current != null) && !current.isResolved() && (current != highest))
+            {
+                if (Util.isFragment(current))
+                {
+                    removeFragment(current);
+                }
+                else
+                {
+                    removeHost(current);
+                }
+            }
+            else if (current != null)
+            {
+                module = null;
+            }
         }
-        else
+
+        if ((module != null) && Util.isFragment(module))
+        {
+             addFragment(module);
+        }
+        else if (module != null)
         {
             addHost(module);
         }
@@ -76,8 +128,20 @@
 //dumpPackageIndex(m_resolvedPkgIndex);
     }
 
-    public synchronized void removeModule(IModule module)
+    public synchronized void removeModule(Module module)
     {
+        // If this module is a singleton, then remove it from the
+        // singleton map.
+        List<Module> modules = m_singletons.get(module.getSymbolicName());
+        if (modules != null)
+        {
+            modules.remove(module);
+            if (modules.size() == 0)
+            {
+                m_singletons.remove(module.getSymbolicName());
+            }
+        }
+
         if (Util.isFragment(module))
         {
             removeFragment(module);
@@ -88,10 +152,75 @@
         }
     }
 
-    private void addFragment(IModule fragment)
+    public void detachFragment(Module host, Module fragment)
+    {
+        List<Module> fragments = ((ModuleImpl) host).getFragments();
+        fragments.remove(fragment);
+        try
+        {
+            ((ModuleImpl) host).attachFragments(fragments);
+        }
+        catch (Exception ex)
+        {
+            // Try to clean up by removing all fragments.
+            try
+            {
+                ((ModuleImpl) host).attachFragments(null);
+            }
+            catch (Exception ex2)
+            {
+            }
+            m_logger.log(Logger.LOG_ERROR,
+                "Serious error attaching fragments.", ex);
+        }
+    }
+
+    public void checkSingleton(Module module)
+    {
+        // Check if this module is a singleton.
+        List<Module> modules = m_singletons.get(module.getSymbolicName());
+        if ((modules != null) && modules.contains(module))
+        {
+            // If it is, check if there is already a resolved singleton.
+            for (int i = 0; (modules != null) && (i < modules.size()); i++)
+            {
+                if (modules.get(i).isResolved())
+                {
+                    throw new ResolveException(
+                        "Only one singleton can be resolved at a time.", null, null);
+                }
+            }
+
+            // If not, check to see if it is the selected singleton.
+            Module current = (modules.size() > 0) ? modules.get(0) : null;
+            if ((current != null) && (current != module))
+            {
+                // If it is not the selected singleton, remove the selected
+                // singleton and select the specified one instead.
+                if (Util.isFragment(current))
+                {
+                    removeFragment(current);
+                }
+                else
+                {
+                    removeHost(current);
+                }
+                if (Util.isFragment(module))
+                {
+                     addFragment(module);
+                }
+                else if (module != null)
+                {
+                    addHost(module);
+                }
+            }
+        }
+    }
+
+    private void addFragment(Module fragment)
     {
 // TODO: FRAGMENT - This should check to make sure that the host allows fragments.
-        IModule bestFragment = indexFragment(m_fragmentMap, fragment);
+        Module bestFragment = indexModule(m_fragmentMap, fragment);
 
         // If the newly added fragment is the highest version for
         // its given symbolic name, then try to merge it to any
@@ -107,20 +236,20 @@
             List matchingHosts = getMatchingHosts(fragment);
             for (int hostIdx = 0; hostIdx < matchingHosts.size(); hostIdx++)
             {
-                IModule host = ((ICapability) matchingHosts.get(hostIdx)).getModule();
+                Module host = ((Capability) matchingHosts.get(hostIdx)).getModule();
 
                 // Get the fragments currently attached to the host so we
                 // can remove the older version of the current fragment, if any.
-                IModule[] fragments = ((ModuleImpl) host).getFragments();
-                List fragmentList = new ArrayList();
+                List<Module> fragments = ((ModuleImpl) host).getFragments();
+                List<Module> fragmentList = new ArrayList();
                 for (int fragIdx = 0;
-                    (fragments != null) && (fragIdx < fragments.length);
+                    (fragments != null) && (fragIdx < fragments.size());
                     fragIdx++)
                 {
-                    if (!fragments[fragIdx].getSymbolicName().equals(
+                    if (!fragments.get(fragIdx).getSymbolicName().equals(
                         bestFragment.getSymbolicName()))
                     {
-                        fragmentList.add(fragments[fragIdx]);
+                        fragmentList.add(fragments.get(fragIdx));
                     }
                 }
 
@@ -130,7 +259,7 @@
                     (index < 0) && (listIdx < fragmentList.size());
                     listIdx++)
                 {
-                    IModule f = (IModule) fragmentList.get(listIdx);
+                    Module f = fragmentList.get(listIdx);
                     if (bestFragment.getBundle().getBundleId()
                         < f.getBundle().getBundleId())
                     {
@@ -141,30 +270,21 @@
                     (index < 0) ? fragmentList.size() : index, bestFragment);
 
                 // Remove host's existing exported packages from index.
-                ICapability[] caps = host.getCapabilities();
-                for (int i = 0; (caps != null) && (i < caps.length); i++)
+                List<Capability> caps = host.getCapabilities();
+                for (int i = 0; (caps != null) && (i < caps.size()); i++)
                 {
-                    if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                    if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
                     {
-                        // Get package name.
-                        String pkgName = (String)
-                            caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                        // Remove from "unresolved" package map.
-                        List capList = (List) m_unresolvedPkgIndex.get(pkgName);
-                        if (capList != null)
-                        {
-                            capList.remove(caps[i]);
-                        }
+                        m_modCapSet.removeCapability(caps.get(i));
+                    }
+                    else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    {
+                        m_pkgCapSet.removeCapability(caps.get(i));
                     }
                 }
 
-                // Check if fragment conflicts with existing metadata.
-                checkForConflicts(host, fragmentList);
-
                 // Attach the fragments to the host.
-                fragments = (fragmentList.size() == 0)
-                    ? null
-                    : (IModule[]) fragmentList.toArray(new IModule[fragmentList.size()]);
+                fragments = (fragmentList.size() == 0) ? null : fragmentList;
                 try
                 {
                     ((ModuleImpl) host).attachFragments(fragments);
@@ -185,18 +305,22 @@
 
                 // Reindex the host's exported packages.
                 caps = host.getCapabilities();
-                for (int i = 0; (caps != null) && (i < caps.length); i++)
+                for (int i = 0; (caps != null) && (i < caps.size()); i++)
                 {
-                    if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                    if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
                     {
-                        indexPackageCapability(m_unresolvedPkgIndex, caps[i]);
+                        m_modCapSet.addCapability(caps.get(i));
+                    }
+                    else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    {
+                        m_pkgCapSet.addCapability(caps.get(i));
                     }
                 }
             }
         }
     }
 
-    private void removeFragment(IModule fragment)
+    private void removeFragment(Module fragment)
     {
         // Get fragment list, which may be null for system bundle fragments.
         List fragList = (List) m_fragmentMap.get(fragment.getSymbolicName());
@@ -216,71 +340,60 @@
             List matchingHosts = getMatchingHosts(fragment);
             for (int hostIdx = 0; hostIdx < matchingHosts.size(); hostIdx++)
             {
-                IModule host = ((ICapability) matchingHosts.get(hostIdx)).getModule();
+                Module host = ((Capability) matchingHosts.get(hostIdx)).getModule();
 
                 // Check to see if the removed fragment was actually merged with
                 // the host, since it might not be if it wasn't the highest version.
                 // If it was, recalculate the fragments for the host.
-                IModule[] fragments = ((ModuleImpl) host).getFragments();
-                for (int fragIdx = 0;
-                    (fragments != null) && (fragIdx < fragments.length);
-                    fragIdx++)
+                List<Module> fragments = ((ModuleImpl) host).getFragments();
+                if (fragments.contains(fragment))
                 {
-                    if (!fragments[fragIdx].equals(fragment))
+                    List fragmentList = getMatchingFragments(host);
+
+                    // Remove host's existing exported packages from index.
+                    List<Capability> caps = host.getCapabilities();
+                    for (int i = 0; (caps != null) && (i < caps.size()); i++)
                     {
-                        List fragmentList = getMatchingFragments(host);
-
-                        // Remove host's existing exported packages from index.
-                        ICapability[] caps = host.getCapabilities();
-                        for (int i = 0; (caps != null) && (i < caps.length); i++)
+                        if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
                         {
-                            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            {
-                                // Get package name.
-                                String pkgName = (String)
-                                    caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                                // Remove from "unresolved" package map.
-                                List capList = (List) m_unresolvedPkgIndex.get(pkgName);
-                                if (capList != null)
-                                {
-                                    capList.remove(caps[i]);
-                                }
-                            }
+                            m_modCapSet.removeCapability(caps.get(i));
                         }
+                        else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                        {
+                            m_pkgCapSet.removeCapability(caps.get(i));
+                        }
+                    }
 
-                        // Check if fragment conflicts with existing metadata.
-                        checkForConflicts(host, fragmentList);
-
-                        // Attach the fragments to the host.
-                        fragments = (fragmentList.size() == 0)
-                            ? null
-                            : (IModule[]) fragmentList.toArray(new IModule[fragmentList.size()]);
+                    // Attach the fragments to the host.
+                    try
+                    {
+                        ((ModuleImpl) host).attachFragments(fragmentList);
+                    }
+                    catch (Exception ex)
+                    {
+                        // Try to clean up by removing all fragments.
                         try
                         {
-                            ((ModuleImpl) host).attachFragments(fragments);
+                            ((ModuleImpl) host).attachFragments(null);
                         }
-                        catch (Exception ex)
+                        catch (Exception ex2)
                         {
-                            // Try to clean up by removing all fragments.
-                            try
-                            {
-                                ((ModuleImpl) host).attachFragments(null);
-                            }
-                            catch (Exception ex2)
-                            {
-                            }
-                            m_logger.log(Logger.LOG_ERROR,
-                                "Serious error attaching fragments.", ex);
                         }
+                        m_logger.log(Logger.LOG_ERROR,
+                            "Serious error attaching fragments.", ex);
+                    }
 
-                        // Reindex the host's exported packages.
-                        caps = host.getCapabilities();
-                        for (int i = 0; (caps != null) && (i < caps.length); i++)
+                    // Reindex the host's exported packages.
+                    caps = host.getCapabilities();
+                    for (int i = 0; (caps != null) && (i < caps.size()); i++)
+                    {
+                        if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
                         {
-                            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            {
-                                indexPackageCapability(m_unresolvedPkgIndex, caps[i]);
-                            }
+                            m_modCapSet.addCapability(caps.get(i));
+                        }
+                        else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                        {
+                            m_pkgCapSet.addCapability(caps.get(i));
                         }
                     }
                 }
@@ -288,105 +401,20 @@
         }
     }
 
-    public void unmergeFragment(IModule module)
+    public void unmergeFragment(Module fragment)
     {
-        if (!Util.isFragment(module))
+        if (!Util.isFragment(fragment))
         {
             return;
         }
 
-        // Get fragment list, which may be null for system bundle fragments.
-        List fragList = (List) m_fragmentMap.get(module.getSymbolicName());
-        if (fragList != null)
-        {
-            // Remove from fragment map.
-            fragList.remove(module);
-            if (fragList.size() == 0)
-            {
-                m_fragmentMap.remove(module.getSymbolicName());
-            }
-
-            // If we have any matching hosts, then remove fragment while
-            // removing any older version of the new fragment. Also remove host's
-            // existing capabilities from the package index and reindex its new
-            // ones after attaching the fragment.
-            List matchingHosts = getMatchingHosts(module);
-            for (int hostIdx = 0; hostIdx < matchingHosts.size(); hostIdx++)
-            {
-                IModule host = ((ICapability) matchingHosts.get(hostIdx)).getModule();
-                // Find any unresolved hosts into which the fragment is merged
-                // and unmerge it.
-                IModule[] fragments = ((ModuleImpl) host).getFragments();
-                for (int fragIdx = 0;
-                    !host.isResolved() && (fragments != null) && (fragIdx < fragments.length);
-                    fragIdx++)
-                {
-                    if (!fragments[fragIdx].equals(module))
-                    {
-                        List fragmentList = getMatchingFragments(host);
-
-                        // Remove host's existing exported packages from index.
-                        ICapability[] caps = host.getCapabilities();
-                        for (int i = 0; (caps != null) && (i < caps.length); i++)
-                        {
-                            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            {
-                                // Get package name.
-                                String pkgName = (String)
-                                    caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                                // Remove from "unresolved" package map.
-                                List capList = (List) m_unresolvedPkgIndex.get(pkgName);
-                                if (capList != null)
-                                {
-                                    capList.remove(caps[i]);
-                                }
-                            }
-                        }
-
-                        // Check if fragment conflicts with existing metadata.
-                        checkForConflicts(host, fragmentList);
-
-                        // Attach the fragments to the host.
-                        fragments = (fragmentList.size() == 0)
-                            ? null
-                            : (IModule[]) fragmentList.toArray(new IModule[fragmentList.size()]);
-                        try
-                        {
-                            ((ModuleImpl) host).attachFragments(fragments);
-                        }
-                        catch (Exception ex)
-                        {
-                            // Try to clean up by removing all fragments.
-                            try
-                            {
-                                ((ModuleImpl) host).attachFragments(null);
-                            }
-                            catch (Exception ex2)
-                            {
-                            }
-                            m_logger.log(Logger.LOG_ERROR,
-                                "Serious error attaching fragments.", ex);
-                        }
-
-                        // Reindex the host's exported packages.
-                        caps = host.getCapabilities();
-                        for (int i = 0; (caps != null) && (i < caps.length); i++)
-                        {
-                            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            {
-                                indexPackageCapability(m_unresolvedPkgIndex, caps[i]);
-                            }
-                        }
-                    }
-                }
-            }
-        }
+        removeFragment(fragment);
     }
 
-    private List getMatchingHosts(IModule fragment)
+    private List getMatchingHosts(Module fragment)
     {
         // Find the fragment's host requirement.
-        IRequirement hostReq = getFragmentHostRequirement(fragment);
+        Requirement hostReq = getFragmentHostRequirement(fragment);
 
         // Create a list of all matching hosts for this fragment.
         List matchingHosts = new ArrayList();
@@ -399,32 +427,26 @@
                 return matchingHosts;
             }
         }
-        for (int hostIdx = 0; (hostReq != null) && (hostIdx < m_moduleList.size()); hostIdx++)
+
+        Set<Capability> hostCaps = m_hostCapSet.match(hostReq.getFilter(), true);
+
+        for (Capability hostCap : hostCaps)
         {
-            IModule host = (IModule) m_moduleList.get(hostIdx);
             // Only look at unresolved hosts, since we don't support
             // dynamic attachment of fragments.
-            if (host.isResolved()
-                || ((BundleImpl) host.getBundle()).isStale()
-                || ((BundleImpl) host.getBundle()).isRemovalPending())
+            if (hostCap.getModule().isResolved()
+                || ((BundleImpl) hostCap.getModule().getBundle()).isStale()
+                || ((BundleImpl) hostCap.getModule().getBundle()).isRemovalPending())
             {
                 continue;
             }
 
-            // Find the host capability for the current host.
-            ICapability hostCap = Util.getSatisfyingCapability(host, hostReq);
-
-            // If there is no host capability in the current module,
-            // then just ignore it.
-            if (hostCap == null)
-            {
-                continue;
-            }
-            
             if (sm != null)
             {
-                if (!((BundleProtectionDomain) host.getSecurityContext()).impliesDirect(new BundlePermission(host.getSymbolicName(), 
-                    BundlePermission.HOST)))
+                if (!((BundleProtectionDomain) hostCap.getModule()
+                        .getSecurityContext()).impliesDirect(
+                            new BundlePermission(hostCap.getModule().getSymbolicName(),
+                            BundlePermission.HOST)))
                 {
                     continue;
                 }
@@ -436,280 +458,28 @@
         return matchingHosts;
     }
 
-    private void checkForConflicts(IModule host, List fragmentList)
-    {
-        if ((fragmentList == null) || (fragmentList.size() == 0))
-        {
-            return;
-        }
-
-        // Verify the fragments do not have conflicting imports.
-        // For now, just check for duplicate imports, but in the
-        // future we might want to make this more fine grained.
-        // First get the host's imported packages.
-        final int MODULE_IDX = 0, REQ_IDX = 1;
-        Map ipMerged = new HashMap();
-        Map rbMerged = new HashMap();
-        IRequirement[] reqs = host.getRequirements();
-        for (int reqIdx = 0; (reqs != null) && (reqIdx < reqs.length); reqIdx++)
-        {
-            if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                ipMerged.put(
-                    ((Requirement) reqs[reqIdx]).getTargetName(),
-                    new Object[] { host, reqs[reqIdx] });
-            }
-            else if (reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                rbMerged.put(
-                    ((Requirement) reqs[reqIdx]).getTargetName(),
-                    new Object[] { host, reqs[reqIdx] });
-            }
-        }
-        // Loop through each fragment verifying it does not conflict.
-        // Add its package and bundle dependencies if they do not
-        // conflict or remove the fragment if it does conflict.
-        for (Iterator it = fragmentList.iterator(); it.hasNext(); )
-        {
-            IModule fragment = (IModule) it.next();
-            reqs = fragment.getRequirements();
-            Map ipFragment = new HashMap();
-            Map rbFragment = new HashMap();
-            for (int reqIdx = 0;
-                (reqs != null) && (reqIdx < reqs.length);
-                reqIdx++)
-            {
-                if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                    || reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-                {
-                    String targetName = ((Requirement) reqs[reqIdx]).getTargetName();
-                    Map mergedReqMap =
-                        (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            ? ipMerged : rbMerged;
-                    Map fragmentReqMap =
-                        (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            ? ipFragment : rbFragment;
-                    Object[] existing = (Object[]) mergedReqMap.get(targetName);
-                    if (existing == null)
-                    {
-                        fragmentReqMap.put(targetName, new Object[] { fragment, reqs[reqIdx] });
-                    }
-                    else if (isRequirementConflicting(
-                        (Requirement) existing[REQ_IDX], (Requirement) reqs[reqIdx]))
-                    {
-                        ipFragment.clear();
-                        rbFragment.clear();
-                        it.remove();
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "Excluding fragment " + fragment.getSymbolicName()
-                            + " from " + host.getSymbolicName()
-                            + " due to conflict with "
-                            + (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                                ? "imported package " : "required bundle ")
-                            + targetName + " from "
-                            + ((IModule) existing[MODULE_IDX]).getSymbolicName());
-                        // No need to finish processing current fragment.
-                        break;
-                    }
-                    else
-                    {
-                        // If there is an overlapping requirement for the existing
-                        // target, then try to calculate the intersecting requirement
-                        // and set the existing requirement to that instead. This
-                        // makes it so version ranges do not have to be exact, just
-                        // overlapping.
-                        Requirement intersection = calculateVersionIntersection(
-                            (Requirement) existing[REQ_IDX], (Requirement) reqs[reqIdx]);
-                        if (intersection != existing[REQ_IDX])
-                        {
-                            existing[REQ_IDX] = intersection;
-                        }
-                    }
-                }
-            }
-
-            // Merge non-conflicting requirements into overall set
-            // of requirements and continue checking for conflicts
-            // with the next fragment.
-            for (Iterator it2 = ipFragment.entrySet().iterator(); it2.hasNext(); )
-            {
-                Map.Entry entry = (Map.Entry) it2.next();
-                ipMerged.put(entry.getKey(), entry.getValue());
-            }
-            for (Iterator it2 = rbFragment.entrySet().iterator(); it2.hasNext(); )
-            {
-                Map.Entry entry = (Map.Entry) it2.next();
-                rbMerged.put(entry.getKey(), entry.getValue());
-            }
-        }
-    }
-
-    private boolean isRequirementConflicting(
-        Requirement existing, Requirement additional)
-    {
-        // If the namespace is not the same, then they do NOT conflict.
-        if (!existing.getNamespace().equals(additional.getNamespace()))
-        {
-            return false;
-        }
-        // If the target name is not the same, then they do NOT conflict.
-        if (!existing.getTargetName().equals(additional.getTargetName()))
-        {
-            return false;
-        }
-        // If the existing version range floor is greater than the additional
-        // version range's floor, then they are inconflict since we cannot
-        // widen the constraint.
-        if (!existing.getTargetVersionRange().intersects(
-            additional.getTargetVersionRange()))
-        {
-            return true;
-        }
-        // If optionality is not the same, then they conflict, unless
-        // the existing requirement is not optional, then it doesn't matter
-        // what subsequent requirements are since non-optional is stronger
-        // than optional.
-        if (existing.isOptional() && !additional.isOptional())
-        {
-            return true;
-        }
-        // Verify directives are the same.
-        final R4Directive[] exDirs = (existing.getDirectives() == null)
-            ? new R4Directive[0] : existing.getDirectives();
-        final R4Directive[] addDirs = (additional.getDirectives() == null)
-            ? new R4Directive[0] : additional.getDirectives();
-        // Put attributes in a map, since ordering is arbitrary.
-        final Map exDirMap = new HashMap();
-        for (int i = 0; i < exDirs.length; i++)
-        {
-            exDirMap.put(exDirs[i].getName(), exDirs[i]);
-        }
-        // If attribute values do not match, then they conflict.
-        for (int i = 0; i < addDirs.length; i++)
-        {
-            // Ignore resolution directive, since we've already tested it above.
-            if (!addDirs[i].getName().equals(Constants.RESOLUTION_DIRECTIVE))
-            {
-                final R4Directive exDir = (R4Directive) exDirMap.get(addDirs[i].getName());
-                if ((exDir == null) ||
-                    !exDir.getValue().equals(addDirs[i].getValue()))
-                {
-                    return true;
-                }
-            }
-        }
-        // Verify attributes are the same.
-        final R4Attribute[] exAttrs = (existing.getAttributes() == null)
-            ? new R4Attribute[0] : existing.getAttributes();
-        final R4Attribute[] addAttrs = (additional.getAttributes() == null)
-            ? new R4Attribute[0] : additional.getAttributes();
-        // Put attributes in a map, since ordering is arbitrary.
-        final Map exAttrMap = new HashMap();
-        for (int i = 0; i < exAttrs.length; i++)
-        {
-            exAttrMap.put(exAttrs[i].getName(), exAttrs[i]);
-        }
-        // If attribute values do not match, then they conflict.
-        for (int i = 0; i < addAttrs.length; i++)
-        {
-            // Ignore version property, since we've already tested it above.
-            if (!(additional.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                && addAttrs[i].getName().equals(ICapability.VERSION_PROPERTY))
-                && !(additional.getNamespace().equals(ICapability.MODULE_NAMESPACE)
-                    && addAttrs[i].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE)))
-            {
-                final R4Attribute exAttr = (R4Attribute) exAttrMap.get(addAttrs[i].getName());
-                if ((exAttr == null) ||
-                    !exAttr.getValue().equals(addAttrs[i].getValue()) ||
-                    (exAttr.isMandatory() != addAttrs[i].isMandatory()))
-                {
-                    return true;
-                }
-            }
-        }
-        // They do no conflict.
-        return false;
-    }
-
-    static Requirement calculateVersionIntersection(
-        Requirement existing, Requirement additional)
-    {
-        Requirement intersection = existing;
-        int existVersionIdx = -1, addVersionIdx = -1;
-
-        // Find the existing version attribute.
-        for (int i = 0; (existVersionIdx < 0) && (i < existing.getAttributes().length); i++)
-        {
-            if ((existing.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                && existing.getAttributes()[i].getName().equals(ICapability.VERSION_PROPERTY))
-                || (existing.getNamespace().equals(ICapability.MODULE_NAMESPACE)
-                    && existing.getAttributes()[i].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE)))
-            {
-                existVersionIdx = i;
-            }
-        }
-
-        // Find the additional version attribute.
-        for (int i = 0; (addVersionIdx < 0) && (i < additional.getAttributes().length); i++)
-        {
-            if ((additional.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                && additional.getAttributes()[i].getName().equals(ICapability.VERSION_PROPERTY))
-                || (additional.getNamespace().equals(ICapability.MODULE_NAMESPACE)
-                    && additional.getAttributes()[i].getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE)))
-            {
-                addVersionIdx = i;
-            }
-        }
-
-        // Use the additional requirement's version range if it
-        // has one and the existing requirement does not.
-        if ((existVersionIdx == -1) && (addVersionIdx != -1))
-        {
-            intersection = additional;
-        }
-        // If both requirements have version ranges, then create
-        // a new requirement with an intersecting version range.
-        else if ((existVersionIdx != -1) && (addVersionIdx != -1))
-        {
-            VersionRange vr = ((VersionRange) existing.getAttributes()[existVersionIdx].getValue())
-                .intersection((VersionRange) additional.getAttributes()[addVersionIdx].getValue());
-            R4Attribute[] attrs = existing.getAttributes();
-            R4Attribute[] newAttrs = new R4Attribute[attrs.length];
-            System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-            newAttrs[existVersionIdx] = new R4Attribute(
-                attrs[existVersionIdx].getName(), vr, false);
-            intersection = new Requirement(
-                existing.getNamespace(),
-                existing.getDirectives(),
-                newAttrs);
-        }
-
-        return intersection;
-    }
-
-    private void addHost(IModule host)
+    private void addHost(Module host)
     {
         // When a module is added, we first need to pre-merge any potential fragments
         // into the host and then second create an aggregated list of unresolved
         // capabilities to simplify later processing when resolving bundles.
-        m_moduleList.add(host);
+        m_modules.add(host);
+        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
+        if (caps.size() > 0)
+        {
+            m_hostCapSet.addCapability(caps.get(0));
+        }
 
         //
         // First, merge applicable fragments.
         //
 
-        List fragmentList = getMatchingFragments(host);
+        List<Module> fragments = getMatchingFragments(host);
 
         // Attach any fragments we found for this host.
-        if (fragmentList.size() > 0)
+        if (fragments.size() > 0)
         {
-            // Check if fragment conflicts with existing metadata.
-            checkForConflicts(host, fragmentList);
-
             // Attach the fragments to the host.
-            IModule[] fragments =
-                (IModule[]) fragmentList.toArray(new IModule[fragmentList.size()]);
             try
             {
                 ((ModuleImpl) host).attachFragments(fragments);
@@ -733,52 +503,47 @@
         // Second, index module's capabilities.
         //
 
-        ICapability[] caps = host.getCapabilities();
+        caps = host.getCapabilities();
 
         // Add exports to unresolved package map.
-        for (int i = 0; (caps != null) && (i < caps.length); i++)
+        for (int i = 0; (caps != null) && (i < caps.size()); i++)
         {
-            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
-                indexPackageCapability(m_unresolvedPkgIndex, caps[i]);
+                m_modCapSet.addCapability(caps.get(i));
+            }
+            else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            {
+                m_pkgCapSet.addCapability(caps.get(i));
             }
         }
     }
 
-    private void removeHost(IModule host)
+    private void removeHost(Module host)
     {
         // We need remove the host's exports from the "resolved" and
         // "unresolved" package maps, remove its dependencies on fragments
         // and exporters, and remove it from the module list.
-        m_moduleList.remove(host);
-
-        // Remove exports from package maps.
-        ICapability[] caps = host.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.length); i++)
+        m_modules.remove(host);
+        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
+        if (caps.size() > 0)
         {
-            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                // Get package name.
-                String pkgName = (String)
-                    caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                // Remove from "unresolved" package map.
-                List capList = (List) m_unresolvedPkgIndex.get(pkgName);
-                if (capList != null)
-                {
-                    capList.remove(caps[i]);
-                }
-
-                // Remove from "resolved" package map.
-                capList = (List) m_resolvedPkgIndex.get(pkgName);
-                if (capList != null)
-                {
-                    capList.remove(caps[i]);
-                }
-            }
+            m_hostCapSet.removeCapability(caps.get(0));
         }
 
-        // Remove the module from the "resolved" map.
-        m_resolvedCapMap.remove(host);
+        // Remove exports from package maps.
+        caps = host.getCapabilities();
+        for (int i = 0; (caps != null) && (i < caps.size()); i++)
+        {
+            if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
+            {
+                m_modCapSet.removeCapability(caps.get(i));
+            }
+            else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            {
+                m_pkgCapSet.removeCapability(caps.get(i));
+            }
+        }
 
         // Set fragments to null, which will remove the module from all
         // of its dependent fragment modules.
@@ -795,11 +560,11 @@
         ((ModuleImpl) host).setWires(null);
     }
 
-    private List getMatchingFragments(IModule host)
+    private List getMatchingFragments(Module host)
     {
         // Find the host capability for the current host.
-        ICapability[] caps = Util.getCapabilityByNamespace(host, ICapability.HOST_NAMESPACE);
-        ICapability hostCap = (caps.length == 0) ? null : caps[0];
+        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
+        Capability hostCap = (caps.size() == 0) ? null : caps.get(0);
 
         // If we have a host capability, then loop through all fragments trying to
         // find ones that match.
@@ -816,10 +581,10 @@
         {
             Map.Entry entry = (Map.Entry) it.next();
             List fragments = (List) entry.getValue();
-            IModule fragment = null;
+            Module fragment = null;
             for (int i = 0; (fragment == null) && (i < fragments.size()); i++)
             {
-                IModule f = (IModule) fragments.get(i);
+                Module f = (Module) fragments.get(i);
                 if (!((BundleImpl) f.getBundle()).isStale()
                     && !((BundleImpl) f.getBundle()).isRemovalPending())
                 {
@@ -839,11 +604,11 @@
                     continue;
                 }
             }
-            IRequirement hostReq = getFragmentHostRequirement(fragment);
+            Requirement hostReq = getFragmentHostRequirement(fragment);
 
             // If we have a host requirement, then loop through each host and
             // see if it matches the host requirement.
-            if ((hostReq != null) && hostReq.isSatisfied(hostCap))
+            if ((hostReq != null) && CapabilitySet.matches(hostCap, hostReq.getFilter()))
             {
                 // Now add the new fragment in bundle ID order.
                 int index = -1;
@@ -851,7 +616,7 @@
                     (index < 0) && (listIdx < fragmentList.size());
                     listIdx++)
                 {
-                    IModule existing = (IModule) fragmentList.get(listIdx);
+                    Module existing = (Module) fragmentList.get(listIdx);
                     if (fragment.getBundle().getBundleId()
                         < existing.getBundle().getBundleId())
                     {
@@ -866,16 +631,16 @@
         return fragmentList;
     }
 
-    public synchronized IModule findHost(IModule rootModule) throws ResolveException
+    public synchronized Module findHost(Module rootModule) throws ResolveException
     {
-        IModule newRootModule = rootModule;
+        Module newRootModule = rootModule;
         if (Util.isFragment(rootModule))
         {
             List matchingHosts = getMatchingHosts(rootModule);
-            IModule currentBestHost = null;
+            Module currentBestHost = null;
             for (int hostIdx = 0; hostIdx < matchingHosts.size(); hostIdx++)
             {
-                IModule host = ((ICapability) matchingHosts.get(hostIdx)).getModule();
+                Module host = ((Capability) matchingHosts.get(hostIdx)).getModule();
                 if (currentBestHost == null)
                 {
                     currentBestHost = host;
@@ -897,16 +662,16 @@
         return newRootModule;
     }
 
-    private IRequirement getFragmentHostRequirement(IModule fragment)
+    private static Requirement getFragmentHostRequirement(Module fragment)
     {
         // Find the fragment's host requirement.
-        IRequirement[] reqs = fragment.getRequirements();
-        IRequirement hostReq = null;
-        for (int reqIdx = 0; (hostReq == null) && (reqIdx < reqs.length); reqIdx++)
+        List<Requirement> reqs = fragment.getRequirements();
+        Requirement hostReq = null;
+        for (int reqIdx = 0; (hostReq == null) && (reqIdx < reqs.size()); reqIdx++)
         {
-            if (reqs[reqIdx].getNamespace().equals(ICapability.HOST_NAMESPACE))
+            if (reqs.get(reqIdx).getNamespace().equals(Capability.HOST_NAMESPACE))
             {
-                hostReq = reqs[reqIdx];
+                hostReq = reqs.get(reqIdx);
             }
         }
         return hostReq;
@@ -918,60 +683,31 @@
      * to capture additional capabilities.
      * @param module The module being refresh, which should always be the system bundle.
     **/
-    synchronized void refreshSystemBundleModule(IModule module)
+    synchronized void refreshSystemBundleModule(Module module)
     {
         // The system bundle module should always be resolved, so we only need
         // to update the resolved capability map.
-        ICapability[] caps = module.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.length); i++)
+        List<Capability> caps = module.getCapabilities();
+        for (int i = 0; (caps != null) && (i < caps.size()); i++)
         {
-            List resolvedCaps = (List) m_resolvedCapMap.get(module);
-            if (resolvedCaps == null)
+            if (caps.get(i).getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
-                m_resolvedCapMap.put(module, resolvedCaps = new ArrayList());
+                m_modCapSet.addCapability(caps.get(i));
             }
-            if (!resolvedCaps.contains(caps[i]))
+            else if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
             {
-                resolvedCaps.add(caps[i]);
-            }
-
-            // If the capability is a package, then add the exporter module
-            // of the wire to the "resolved" package index and remove it
-            // from the "unresolved" package index.
-            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                // Add to "resolved" package index.
-                indexPackageCapability(m_resolvedPkgIndex, caps[i]);
+                m_pkgCapSet.addCapability(caps.get(i));
             }
         }
     }
 
-    private void dumpPackageIndex(Map pkgIndex)
+// TODO: FELIX3 - Try to eliminate this.
+    public synchronized List<Module> getModules()
     {
-        for (Iterator i = pkgIndex.entrySet().iterator(); i.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) i.next();
-            List capList = (List) entry.getValue();
-            if (capList.size() > 0)
-            {
-                if (!((capList.size() == 1) && ((ICapability) capList.get(0)).getModule().getId().equals("0")))
-                {
-                    System.out.println("  " + entry.getKey());
-                    for (int j = 0; j < capList.size(); j++)
-                    {
-                        System.out.println("    " + ((ICapability) capList.get(j)).getModule());
-                    }
-                }
-            }
-        }
+        return m_modules;
     }
 
-    public synchronized IModule[] getModules()
-    {
-        return (IModule[]) m_moduleList.toArray(new IModule[m_moduleList.size()]);
-    }
-
-    public synchronized void moduleResolved(IModule module)
+    public synchronized void moduleResolved(Module module)
     {
         if (module.isResolved())
         {
@@ -983,40 +719,22 @@
             // module and not another module. If it points to another module
             // then the capability should be ignored, since the framework
             // decided to honor the import and discard the export.
-            ICapability[] caps = module.getCapabilities();
+            List<Capability> caps = module.getCapabilities();
 
-            // First remove all existing capabilities from the "unresolved" map.
-            for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
-            {
-                if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                {
-                    // Get package name.
-                    String pkgName = (String)
-                        caps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                    // Remove the module's capability for the package.
-                    List capList = (List) m_unresolvedPkgIndex.get(pkgName);
-                    capList.remove(caps[capIdx]);
-                }
-            }
-
-            // Next create a copy of the module's capabilities so we can
+            // Create a copy of the module's capabilities so we can
             // null out any capabilities that should be ignored.
-            ICapability[] capsCopy = (caps == null) ? null : new ICapability[caps.length];
-            if (capsCopy != null)
-            {
-                System.arraycopy(caps, 0, capsCopy, 0, caps.length);
-            }
+            List<Capability> capsCopy = (caps == null) ? null : new ArrayList(caps);
             // Loop through the module's capabilities to determine which ones
             // can be ignored by seeing which ones satifies the wire requirements.
 // TODO: RB - Bug here because a requirement for a package need not overlap the
 //            capability for that package and this assumes it does. This might
 //            require us to introduce the notion of a substitutable capability.
-            IWire[] wires = module.getWires();
-            for (int capIdx = 0; (capsCopy != null) && (capIdx < capsCopy.length); capIdx++)
+            List<Wire> wires = module.getWires();
+            for (int capIdx = 0; (capsCopy != null) && (capIdx < caps.size()); capIdx++)
             {
                 // Loop through all wires to see if the current capability
                 // satisfies any of the wire requirements.
-                for (int wireIdx = 0; (wires != null) && (wireIdx < wires.length); wireIdx++)
+                for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
                 {
                     // If one of the module's capabilities satifies the requirement
                     // for an existing wire, this means the capability was
@@ -1024,9 +742,10 @@
                     // the module's capability was not used. Therefore, we should
                     // null it here so it doesn't get added the list of resolved
                     // capabilities for this module.
-                    if (wires[wireIdx].getRequirement().isSatisfied(capsCopy[capIdx]))
+                    if (CapabilitySet.matches(
+                        caps.get(capIdx), wires.get(wireIdx).getRequirement().getFilter()))
                     {
-                        capsCopy[capIdx] = null;
+                        capsCopy.remove(caps.get(capIdx));
                         break;
                     }
                 }
@@ -1034,276 +753,72 @@
 
             // Now loop through all capabilities and add them to the "resolved"
             // capability and package index maps, ignoring any that were nulled out.
-            for (int capIdx = 0; (capsCopy != null) && (capIdx < capsCopy.length); capIdx++)
+// TODO: FELIX3 - This is actually reversed, we need to remove exports that were imported.
+/*
+            for (int capIdx = 0; (capsCopy != null) && (capIdx < capsCopy.size()); capIdx++)
             {
-                if (capsCopy[capIdx] != null)
+                if (capsCopy.get(capIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
                 {
-                    List resolvedCaps = (List) m_resolvedCapMap.get(module);
-                    if (resolvedCaps == null)
-                    {
-                        m_resolvedCapMap.put(module, resolvedCaps = new ArrayList());
-                    }
-                    if (!resolvedCaps.contains(capsCopy[capIdx]))
-                    {
-                        resolvedCaps.add(capsCopy[capIdx]);
-                    }
-
-                    // If the capability is a package, then add the exporter module
-                    // of the wire to the "resolved" package index and remove it
-                    // from the "unresolved" package index.
-                    if (capsCopy[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                    {
-                        // Add to "resolved" package index.
-                        indexPackageCapability(m_resolvedPkgIndex, capsCopy[capIdx]);
-                    }
+                    m_modCapSet.addCapability(capsCopy.get(capIdx));
+                }
+                else if (capsCopy.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                {
+                    m_pkgCapSet.addCapability(capsCopy.get(capIdx));
                 }
             }
+*/
         }
-
-//System.out.println("UNRESOLVED PACKAGES:");
-//dumpPackageIndex(m_unresolvedPkgIndex);
-//System.out.println("RESOLVED PACKAGES:");
-//dumpPackageIndex(m_resolvedPkgIndex);
     }
 
-    public synchronized List getResolvedCandidates(IRequirement req, IModule reqModule)
+    public Set<Capability> getCandidates(Module module, Requirement req, boolean obeyMandatory)
     {
-        // Synchronized on the module manager to make sure that no
-        // modules are added, removed, or resolved.
-        List candidates = new ArrayList();
-        if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-            && (((Requirement) req).getTargetName() != null))
-        {
-            String pkgName = ((Requirement) req).getTargetName();
-            List capList = (List) m_resolvedPkgIndex.get(pkgName);
+        Set<Capability> result = new TreeSet(new CandidateComparator());
 
-            for (int capIdx = 0; (capList != null) && (capIdx < capList.size()); capIdx++)
-            {
-                ICapability cap = (ICapability) capList.get(capIdx);
-                if (req.isSatisfied(cap))
-                {
-                    if (System.getSecurityManager() != null)
-                    {
-                        if (reqModule != ((ICapability) capList.get(capIdx)).getModule())
-                        {
-                            if ((!((BundleProtectionDomain)((ICapability) 
-                                capList.get(capIdx)).getModule().getSecurityContext()).impliesDirect(
-                                new PackagePermission(((Requirement) req).getTargetName(), PackagePermission.EXPORTONLY))) ||
-                                !((reqModule == null) ||
-                                ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                                new PackagePermission(((Requirement) req).getTargetName(), ((ICapability) 
-                                capList.get(capIdx)).getModule().getBundle(),PackagePermission.IMPORT))
-                                ))
-                            {
-                                continue;
-                            }
-                        }
-                    }
-                    candidates.add(cap);
-                }
-            }
-        }
-        else
+        if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
         {
-            Iterator i = m_resolvedCapMap.entrySet().iterator();
-            while (i.hasNext())
-            {
-                Map.Entry entry = (Map.Entry) i.next();
-                IModule module = (IModule) entry.getKey();
-                List caps = (List) entry.getValue();
-                for (int capIdx = 0; (caps != null) && (capIdx < caps.size()); capIdx++)
-                {
-                    ICapability cap = (ICapability) caps.get(capIdx);
-                    if (req.isSatisfied(cap))
-                    {
-                        if (System.getSecurityManager() != null)
-                        {
-                            if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) && (
-                                !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                                new PackagePermission((String) cap.getProperties().get(ICapability.PACKAGE_PROPERTY), PackagePermission.EXPORTONLY)) ||
-                                !((reqModule == null) ||
-                                ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                                new PackagePermission((String) cap.getProperties().get(ICapability.PACKAGE_PROPERTY), cap.getModule().getBundle(),PackagePermission.IMPORT))
-                                )))
-                            {
-                                if (reqModule != cap.getModule())
-                                {
-                                    continue;
-                                }
-                            }
-                            if (req.getNamespace().equals(ICapability.MODULE_NAMESPACE) && (
-                                !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                                new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
-                                !((reqModule == null) ||
-                                ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                                new BundlePermission(reqModule.getSymbolicName(), BundlePermission.REQUIRE))
-                                )))
-                            {
-                                continue;
-                            }
-                        }
-                        candidates.add(cap);
-                    }
-                }
-            }
+            result.addAll(m_modCapSet.match(req.getFilter(), obeyMandatory));
         }
-        Collections.sort(candidates);
-        return candidates;
-    }
-
-    public synchronized List getUnresolvedCandidates(IRequirement req, IModule reqModule)
-    {
-        // Get all matching unresolved capabilities.
-        List candidates = new ArrayList();
-        if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-            (((Requirement) req).getTargetName() != null))
+        else if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
         {
-            List capList = (List) m_unresolvedPkgIndex.get(((Requirement) req).getTargetName());
-            for (int capIdx = 0; (capList != null) && (capIdx < capList.size()); capIdx++)
-            {
-                // If compatible and it is not currently resolved, then add
-                // the unresolved candidate to the list.
-                if (req.isSatisfied((ICapability) capList.get(capIdx)))
-                {
-                    if (System.getSecurityManager() != null)
-                    {
-                        if (reqModule != ((ICapability) capList.get(capIdx)).getModule())
-                        {
-                            if (!((BundleProtectionDomain)((ICapability) 
-                                capList.get(capIdx)).getModule().getSecurityContext()).impliesDirect(
-                                new PackagePermission(((Requirement) req).getTargetName(), PackagePermission.EXPORTONLY)) ||
-                                !((reqModule == null) ||
-                                ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                                new PackagePermission(((Requirement) req).getTargetName(), ((ICapability) 
-                                capList.get(capIdx)).getModule().getBundle(),PackagePermission.IMPORT))
-                                ))
-                            {
-                                continue;
-                            }
-                        }
-                    }
-                    candidates.add(capList.get(capIdx));
-                }
-            }
-        }
-        else
-        {
-            IModule[] modules = getModules();
-            for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
-            {
-                // Get the module's export package for the target package.
-                ICapability cap = Util.getSatisfyingCapability(modules[modIdx], req);
-                // If compatible and it is not currently resolved, then add
-                // the unresolved candidate to the list.
-                if ((cap != null) && !modules[modIdx].isResolved())
-                {
-                    if (System.getSecurityManager() != null)
-                    {
-                        if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) && (
-                            !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                            new PackagePermission((String) cap.getProperties().get(ICapability.PACKAGE_PROPERTY), PackagePermission.EXPORTONLY)) ||
-                            !((reqModule == null) ||
-                            ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                            new PackagePermission((String) cap.getProperties().get(ICapability.PACKAGE_PROPERTY), cap.getModule().getBundle(),PackagePermission.IMPORT))
-                            )))
-                        {
-                            if (reqModule != cap.getModule())
-                            {
-                                continue;
-                            }
-                        }
-                        if (req.getNamespace().equals(ICapability.MODULE_NAMESPACE) && (
-                                !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                                new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
-                                !((reqModule == null) ||
-                                ((BundleProtectionDomain) reqModule.getSecurityContext()).impliesDirect(
-                                new BundlePermission(reqModule.getSymbolicName(), BundlePermission.REQUIRE))
-                                )))
-                            {
-                                continue;
-                            }
-                    }
-                    candidates.add(cap);
-                }
-            }
+            result.addAll(m_pkgCapSet.match(req.getFilter(), obeyMandatory));
         }
 
-        // Create list of compatible providers.
-        Collections.sort(candidates);
-        return candidates;
+        return result;
     }
 
     //
     // Utility methods.
     //
 
-    private void indexPackageCapability(Map map, ICapability capability)
+    /**
+     * Returns true if the specified module is a singleton
+     * (i.e., directive singleton:=true in Bundle-SymbolicName).
+     *
+     * @param module the module to check for singleton status.
+     * @return true if the module is a singleton, false otherwise.
+    **/
+    private static boolean isSingleton(Module module)
     {
-        if (capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+        final List<Capability> modCaps =
+            Util.getCapabilityByNamespace(
+                module, Capability.MODULE_NAMESPACE);
+        if (modCaps == null || modCaps.size() == 0)
         {
-            String pkgName = (String)
-                capability.getProperties().get(ICapability.PACKAGE_PROPERTY);
-            List capList = (List) map.get(pkgName);
-
-            // We want to add the capability into the list of exporters
-            // in sorted order (descending version and ascending bundle
-            // identifier). Insert using a simple binary search algorithm.
-            if (capList == null)
-            {
-                capList = new ArrayList();
-                capList.add(capability);
-            }
-            else
-            {
-                Version version = (Version)
-                    capability.getProperties().get(ICapability.VERSION_PROPERTY);
-                Version middleVersion = null;
-                int top = 0, bottom = capList.size() - 1, middle = 0;
-                while (top <= bottom)
-                {
-                    middle = (bottom - top) / 2 + top;
-                    middleVersion = (Version)
-                        ((ICapability) capList.get(middle))
-                            .getProperties().get(ICapability.VERSION_PROPERTY);
-                    // Sort in reverse version order.
-                    int cmp = middleVersion.compareTo(version);
-                    if (cmp < 0)
-                    {
-                        bottom = middle - 1;
-                    }
-                    else if (cmp == 0)
-                    {
-                        // Sort further by ascending bundle ID.
-                        long middleId = ((ICapability) capList.get(middle))
-                            .getModule().getBundle().getBundleId();
-                        long exportId = capability.getModule().getBundle().getBundleId();
-                        if (middleId < exportId)
-                        {
-                            top = middle + 1;
-                        }
-                        else
-                        {
-                            bottom = middle - 1;
-                        }
-                    }
-                    else
-                    {
-                        top = middle + 1;
-                    }
-                }
-
-                // Ignore duplicates.
-                if ((top >= capList.size()) || (capList.get(top) != capability))
-                {
-                    capList.add(top, capability);
-                }
-            }
-
-            map.put(pkgName, capList);
+            return false;
         }
+        final List<Directive> dirs = modCaps.get(0).getDirectives();
+        for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.size()); dirIdx++)
+        {
+            if (dirs.get(dirIdx).getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
+                && Boolean.valueOf((String) dirs.get(dirIdx).getValue()).booleanValue())
+            {
+                return true;
+            }
+        }
+        return false;
     }
 
-    private IModule indexFragment(Map map, IModule module)
+    private static Module indexModule(Map map, Module module)
     {
         List modules = (List) map.get(module.getSymbolicName());
 
@@ -1324,7 +839,7 @@
             while (top <= bottom)
             {
                 middle = (bottom - top) / 2 + top;
-                middleVersion = ((IModule) modules.get(middle)).getVersion();
+                middleVersion = ((Module) modules.get(middle)).getVersion();
                 // Sort in reverse version order.
                 int cmp = middleVersion.compareTo(version);
                 if (cmp < 0)
@@ -1334,7 +849,7 @@
                 else if (cmp == 0)
                 {
                     // Sort further by ascending bundle ID.
-                    long middleId = ((IModule) modules.get(middle)).getBundle().getBundleId();
+                    long middleId = ((Module) modules.get(middle)).getBundle().getBundleId();
                     long exportId = module.getBundle().getBundleId();
                     if (middleId < exportId)
                     {
@@ -1360,6 +875,6 @@
 
         map.put(module.getSymbolicName(), modules);
 
-        return (IModule) modules.get(0);
+        return (Module) modules.get(0);
     }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index bb8b007..12aab90 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -18,8 +18,9 @@
  */
 package org.apache.felix.framework;
 
-import org.apache.felix.framework.searchpolicy.*;
-import org.apache.felix.moduleloader.*;
+import org.apache.felix.framework.resolver.ResourceNotFoundException;
+import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
@@ -31,7 +32,7 @@
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -42,29 +43,37 @@
 import java.util.Vector;
 import org.apache.felix.framework.Felix.FelixResolver;
 import org.apache.felix.framework.cache.JarContent;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.WireImpl;
+import org.apache.felix.framework.resolver.WireModuleImpl;
 import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.SecureAction;
 import org.apache.felix.framework.util.SecurityManagerEx;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.Capability;
+import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.util.manifestparser.Requirement;
+import org.apache.felix.framework.util.manifestparser.RequirementImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.BundleReference;
 import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.Version;
 
-public class ModuleImpl implements IModule
+public class ModuleImpl implements Module
 {
     private final Logger m_logger;
     private final Map m_configMap;
     private final FelixResolver m_resolver;
     private final String m_id;
-    private final IContent m_content;
+    private final Content m_content;
     private final Map m_headerMap;
     private final URLStreamHandler m_streamHandler;
 
@@ -73,28 +82,28 @@
     private final String m_symbolicName;
     private final Version m_version;
 
-    private final ICapability[] m_capabilities;
-    private ICapability[] m_cachedCapabilities = null;
-    private final IRequirement[] m_requirements;
-    private IRequirement[] m_cachedRequirements = null;
-    private final IRequirement[] m_dynamicRequirements;
-    private IRequirement[] m_cachedDynamicRequirements = null;
-    private final R4Library[] m_nativeLibraries;
+    private final List<Capability> m_capabilities;
+    private List<Capability> m_cachedCapabilities = null;
+    private final List<Requirement> m_requirements;
+    private List<Requirement> m_cachedRequirements = null;
+    private final List<Requirement> m_dynamicRequirements;
+    private List<Requirement> m_cachedDynamicRequirements = null;
+    private final List<R4Library> m_nativeLibraries;
     private final int m_declaredActivationPolicy;
-    private final String[] m_activationIncludes;
-    private final String[] m_activationExcludes;
+    private final List<String> m_activationIncludes;
+    private final List<String> m_activationExcludes;
 
     private final Bundle m_bundle;
 
-    private IModule[] m_fragments = null;
-    private IWire[] m_wires = null;
-    private IModule[] m_dependentHosts = new IModule[0];
-    private IModule[] m_dependentImporters = new IModule[0];
-    private IModule[] m_dependentRequirers = new IModule[0];
+    private List<Module> m_fragments = null;
+    private List<Wire> m_wires = null;
+    private List<Module> m_dependentHosts = new ArrayList<Module>(0);
+    private List<Module> m_dependentImporters = new ArrayList<Module>(0);
+    private List<Module> m_dependentRequirers = new ArrayList<Module>(0);
     private volatile boolean m_isResolved = false;
 
-    private IContent[] m_contentPath;
-    private IContent[] m_fragmentContents = null;
+    private Content[] m_contentPath;
+    private Content[] m_fragmentContents = null;
     private ModuleClassLoader m_classLoader;
     private boolean m_isActivationTriggered = false;
     private ProtectionDomain m_protectionDomain = null;
@@ -184,7 +193,7 @@
 
     public ModuleImpl(
         Logger logger, Map configMap, FelixResolver resolver,
-        Bundle bundle, String id, Map headerMap, IContent content,
+        Bundle bundle, String id, Map headerMap, Content content,
         URLStreamHandler streamHandler, String[] bootPkgs,
         boolean[] bootPkgWildcards)
         throws BundleException
@@ -269,163 +278,110 @@
         return m_version;
     }
 
-    public synchronized ICapability[] getCapabilities()
+    public synchronized List<Capability> getCapabilities()
     {
         if (m_cachedCapabilities == null)
         {
             List capList = (m_capabilities == null)
-                ? new ArrayList() : new ArrayList(Arrays.asList(m_capabilities));
+                ? new ArrayList<Capability>()
+                : new ArrayList<Capability>(m_capabilities);
             for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.length);
+                (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                ICapability[] caps = m_fragments[fragIdx].getCapabilities();
+                List<Capability> caps = m_fragments.get(fragIdx).getCapabilities();
                 for (int capIdx = 0;
-                    (caps != null) && (capIdx < caps.length);
+                    (caps != null) && (capIdx < caps.size());
                     capIdx++)
                 {
-                    if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                    if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
                     {
                         capList.add(
-                            new Capability(
+                            new CapabilityImpl(
                                 this,
-                                caps[capIdx].getNamespace(),
-                                ((Capability) caps[capIdx]).getDirectives(),
-                                ((Capability) caps[capIdx]).getAttributes()));
+                                caps.get(capIdx).getNamespace(),
+                                caps.get(capIdx).getDirectives(),
+                                caps.get(capIdx).getAttributes()));
                     }
                 }
             }
-            m_cachedCapabilities = (ICapability[])
-                capList.toArray(new ICapability[capList.size()]);
+            m_cachedCapabilities = Collections.unmodifiableList(capList);
         }
         return m_cachedCapabilities;
     }
 
-    public synchronized IRequirement[] getRequirements()
+    public synchronized List<Requirement> getRequirements()
     {
         if (m_cachedRequirements == null)
         {
-            List allReqs = new ArrayList();
-            Map pkgMap = new HashMap();
-            Map rbMap = new HashMap();
-            for (int i = 0; (m_requirements != null) && i < m_requirements.length; i++)
-            {
-                if (m_requirements[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                {
-                    pkgMap.put(
-                        ((Requirement) m_requirements[i]).getTargetName(),
-                        m_requirements[i]);
-                }
-                else if (m_requirements[i].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-                {
-                    rbMap.put(
-                        ((Requirement) m_requirements[i]).getTargetName(),
-                        m_requirements[i]);
-                }
-                else
-                {
-                    allReqs.add(m_requirements[i]);
-                }
-            }
-
-            // Aggregate host and fragment bundle and package requirements.
+            List<Requirement> reqList = (m_requirements == null)
+                ? new ArrayList() : new ArrayList(m_requirements);
             for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.length);
+                (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                IRequirement[] reqs = m_fragments[fragIdx].getRequirements();
+                List<Requirement> reqs = m_fragments.get(fragIdx).getRequirements();
                 for (int reqIdx = 0;
-                    (reqs != null) && (reqIdx < reqs.length);
+                    (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                        || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
                     {
-                        // If the current fragment requirement overlaps a previously
-                        // added requirement, then calculate a new intersecting requirement.
-                        Requirement req = (Requirement) pkgMap.get(
-                            ((Requirement) reqs[reqIdx]).getTargetName());
-                        if (req != null)
-                        {
-                            req = FelixResolverState.calculateVersionIntersection(
-                                req, (Requirement) reqs[reqIdx]);
-                        }
-                        else
-                        {
-                            req = (Requirement) reqs[reqIdx];
-                        }
-                        pkgMap.put(req.getTargetName(), req);
-                    }
-                    else if (reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-                    {
-                        // If the current fragment requirement overlaps a previously
-                        // added requirement, then calculate a new intersecting requirement.
-                        Requirement req = (Requirement) pkgMap.get(
-                            ((Requirement) reqs[reqIdx]).getTargetName());
-                        if (req != null)
-                        {
-                            req = FelixResolverState.calculateVersionIntersection(
-                                req, (Requirement) reqs[reqIdx]);
-                        }
-                        else
-                        {
-                            req = (Requirement) reqs[reqIdx];
-                        }
-                        rbMap.put(req.getTargetName(), req);
+                        reqList.add(
+                            new FragmentRequirement(
+                                reqs.get(reqIdx), m_fragments.get(fragIdx)));
                     }
                 }
             }
-            allReqs.addAll(pkgMap.values());
-            allReqs.addAll(rbMap.values());
-            m_cachedRequirements = (IRequirement[])
-                allReqs.toArray(new IRequirement[allReqs.size()]);
+            m_cachedRequirements = Collections.unmodifiableList(reqList);
         }
         return m_cachedRequirements;
     }
 
-    public synchronized IRequirement[] getDynamicRequirements()
+    public synchronized List<Requirement> getDynamicRequirements()
     {
         if (m_cachedDynamicRequirements == null)
         {
-            List reqList = (m_dynamicRequirements == null)
-                ? new ArrayList() : new ArrayList(Arrays.asList(m_dynamicRequirements));
+            List<Requirement> reqList = (m_dynamicRequirements == null)
+                ? new ArrayList() : new ArrayList(m_dynamicRequirements);
             for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.length);
+                (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                IRequirement[] reqs = m_fragments[fragIdx].getDynamicRequirements();
+                List<Requirement> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
                 for (int reqIdx = 0;
-                    (reqs != null) && (reqIdx < reqs.length);
+                    (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
                     {
-                        reqList.add(reqs[reqIdx]);
+                        reqList.add(reqs.get(reqIdx));
                     }
                 }
             }
-            m_cachedDynamicRequirements = (IRequirement[])
-                reqList.toArray(new IRequirement[reqList.size()]);
+            m_cachedDynamicRequirements = Collections.unmodifiableList(reqList);
         }
         return m_cachedDynamicRequirements;
     }
 
-    public synchronized R4Library[] getNativeLibraries()
+    public synchronized List<R4Library> getNativeLibraries()
     {
-        R4Library[] result = null;
+        List<R4Library> result = null;
         if (m_isResolved)
         {
-            List nativeList = (m_nativeLibraries == null)
-                ? new ArrayList() : new ArrayList(Arrays.asList(m_nativeLibraries));
+            List<R4Library> nativeList = (m_nativeLibraries == null)
+                ? new ArrayList() : new ArrayList(m_nativeLibraries);
             for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.length);
+                (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                R4Library[] libs = m_fragments[fragIdx].getNativeLibraries();
+                List<R4Library> libs = m_fragments.get(fragIdx).getNativeLibraries();
                 for (int reqIdx = 0;
-                    (libs != null) && (reqIdx < libs.length);
+                    (libs != null) && (reqIdx < libs.size());
                     reqIdx++)
                 {
-                    nativeList.add(libs[reqIdx]);
+                    nativeList.add(libs.get(reqIdx));
                 }
             }
 
@@ -434,7 +390,7 @@
             // could not be found when resolving the bundle.
             result = (nativeList.size() == 0)
                 ? null
-                : (R4Library[]) nativeList.toArray(new R4Library[nativeList.size()]);
+                : Collections.unmodifiableList(nativeList);
         }
         else
         {
@@ -465,20 +421,20 @@
         // by default, otherwise try to find one match.
         boolean included = (m_activationIncludes == null);
         for (int i = 0;
-            (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.length);
+            (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.size());
             i++)
         {
-            included = m_activationIncludes[i].equals(pkgName);
+            included = m_activationIncludes.get(i).equals(pkgName);
         }
 
         // If there are no exclude filters then no classes are excluded
         // by default, otherwise try to find one match.
         boolean excluded = false;
         for (int i = 0;
-            (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.length);
+            (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.size());
             i++)
         {
-            excluded = m_activationExcludes[i].equals(pkgName);
+            excluded = m_activationExcludes.get(i).equals(pkgName);
         }
         return included && !excluded;
     }
@@ -497,40 +453,40 @@
         return m_id;
     }
 
-    public synchronized IWire[] getWires()
+    public synchronized List<Wire> getWires()
     {
         return m_wires;
     }
 
-    public synchronized void setWires(IWire[] wires)
+    public synchronized void setWires(List<Wire> wires)
     {
         // Remove module from old wire modules' dependencies,
         // since we are no longer dependent on any the moduels
         // from the old wires.
-        for (int i = 0; (m_wires != null) && (i < m_wires.length); i++)
+        for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
         {
-            if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
-                ((ModuleImpl) m_wires[i].getExporter()).removeDependentRequirer(this);
+                ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentRequirer(this);
             }
-            else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
             {
-                ((ModuleImpl) m_wires[i].getExporter()).removeDependentImporter(this);
+                ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentImporter(this);
             }
         }
 
         m_wires = wires;
 
         // Add ourself as a dependent to the new wires' modules.
-        for (int i = 0; (m_wires != null) && (i < m_wires.length); i++)
+        for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
         {
-            if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
-                ((ModuleImpl) m_wires[i].getExporter()).addDependentRequirer(this);
+                ((ModuleImpl) m_wires.get(i).getExporter()).addDependentRequirer(this);
             }
-            else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
             {
-                ((ModuleImpl) m_wires[i].getExporter()).addDependentImporter(this);
+                ((ModuleImpl) m_wires.get(i).getExporter()).addDependentImporter(this);
             }
         }
     }
@@ -549,12 +505,12 @@
     // Content access methods.
     //
 
-    public IContent getContent()
+    public Content getContent()
     {
         return m_content;
     }
 
-    private synchronized IContent[] getContentPath()
+    private synchronized Content[] getContentPath()
     {
         if (m_contentPath == null)
         {
@@ -570,19 +526,19 @@
         return m_contentPath;
     }
 
-    private IContent[] initializeContentPath() throws Exception
+    private Content[] initializeContentPath() throws Exception
     {
         List contentList = new ArrayList();
         calculateContentPath(this, m_content, contentList, true);
         for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
         {
-            calculateContentPath(m_fragments[i], m_fragmentContents[i], contentList, false);
+            calculateContentPath(m_fragments.get(i), m_fragmentContents[i], contentList, false);
         }
-        return (IContent[]) contentList.toArray(new IContent[contentList.size()]);
+        return (Content[]) contentList.toArray(new Content[contentList.size()]);
     }
 
     private List calculateContentPath(
-        IModule module, IContent content, List contentList, boolean searchFragments)
+        Module module, Content content, List contentList, boolean searchFragments)
         throws Exception
     {
         // Creating the content path entails examining the bundle's
@@ -596,25 +552,25 @@
         // Find class path meta-data.
         String classPath = (String) module.getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
         // Parse the class path into strings.
-        String[] classPathStrings = ManifestParser.parseDelimitedString(
+        List<String> classPathStrings = ManifestParser.parseDelimitedString(
             classPath, FelixConstants.CLASS_PATH_SEPARATOR);
 
         if (classPathStrings == null)
         {
-            classPathStrings = new String[0];
+            classPathStrings = new ArrayList<String>(0);
         }
 
         // Create the bundles class path.
-        for (int i = 0; i < classPathStrings.length; i++)
+        for (int i = 0; i < classPathStrings.size(); i++)
         {
             // Remove any leading slash, since all bundle class path
             // entries are relative to the root of the bundle.
-            classPathStrings[i] = (classPathStrings[i].startsWith("/"))
-                ? classPathStrings[i].substring(1)
-                : classPathStrings[i];
+            classPathStrings.set(i, (classPathStrings.get(i).startsWith("/"))
+                ? classPathStrings.get(i).substring(1)
+                : classPathStrings.get(i));
 
             // Check for the bundle itself on the class path.
-            if (classPathStrings[i].equals(FelixConstants.CLASS_PATH_DOT))
+            if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT))
             {
                 localContentList.add(content);
             }
@@ -622,7 +578,7 @@
             {
                 // Try to find the embedded class path entry in the current
                 // content.
-                IContent embeddedContent = content.getEntryAsContent(classPathStrings[i]);
+                Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
                 // If the embedded class path entry was not found, it might be
                 // in one of the fragments if the current content is the bundle,
                 // so try to search the fragments if necessary.
@@ -631,7 +587,8 @@
                         && (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
                     fragIdx++)
                 {
-                    embeddedContent = m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings[i]);
+                    embeddedContent =
+                        m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings.get(i));
                 }
                 // If we found the embedded content, then add it to the
                 // class path content list.
@@ -645,7 +602,7 @@
 //       need to create an "Eventer" class like "Logger" perhaps.
                     m_logger.log(Logger.LOG_INFO,
                         "Class path entry not found: "
-                        + classPathStrings[i]);
+                        + classPathStrings.get(i));
                 }
             }
         }
@@ -840,7 +797,7 @@
         }
 
         // Check the module class path.
-        IContent[] contentPath = getContentPath();
+        Content[] contentPath = getContentPath();
         for (int i = 0;
             (url == null) &&
             (i < contentPath.length); i++)
@@ -936,15 +893,15 @@
 
         // Note that the search may be aborted if this method throws an
         // exception, otherwise it continues if a null is returned.
-        IWire[] wires = getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
+        List<Wire> wires = getWires();
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
-            if (wires[i] instanceof R4Wire)
+            if (wires.get(i) instanceof WireImpl)
             {
                 try
                 {
                     // If we find the class or resource, then return it.
-                    urls = wires[i].getResources(name);
+                    urls = wires.get(i).getResources(name);
                 }
                 catch (ResourceNotFoundException ex)
                 {
@@ -962,14 +919,14 @@
         // See whether we can get the resource from the required bundles and
         // regardless of whether or not this is the case continue to the next
         // step potentially passing on the result of this search (if any).
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
-            if (wires[i] instanceof R4WireModule)
+            if (wires.get(i) instanceof WireModuleImpl)
             {
                 try
                 {
                     // If we find the class or resource, then add it.
-                    urls = wires[i].getResources(name);
+                    urls = wires.get(i).getResources(name);
                 }
                 catch (ResourceNotFoundException ex)
                 {
@@ -996,10 +953,10 @@
             // At this point, the module's imports were searched and so was the
             // the module's content. Now we make an attempt to load the
             // class/resource via a dynamic import, if possible.
-            IWire wire = null;
+            Wire wire = null;
             try
             {
-                wire = m_resolver.resolveDynamicImport(this, pkgName);
+                wire = m_resolver.resolve(this, pkgName);
             }
             catch (ResolveException ex)
             {
@@ -1033,7 +990,7 @@
         // Special case "/" so that it returns a root URLs for
         // each bundle class path entry...this isn't very
         // clean or meaningful, but the Spring guys want it.
-        final IContent[] contentPath = getContentPath();
+        final Content[] contentPath = getContentPath();
         if (name.equals("/"))
         {
             for (int i = 0; i < contentPath.length; i++)
@@ -1139,8 +1096,8 @@
 
          try
          {
-             return m_secureAction.createURL(null, 
-                 FelixConstants.BUNDLE_URL_PROTOCOL + "://" +  
+             return m_secureAction.createURL(null,
+                 FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
                  m_id + ":" + port + path, m_streamHandler);
          }
          catch (MalformedURLException ex)
@@ -1157,19 +1114,19 @@
     // Fragment and dependency management methods.
     //
 
-    public synchronized IModule[] getFragments()
+    public synchronized List<Module> getFragments()
     {
         return m_fragments;
     }
 
-    public synchronized void attachFragments(IModule[] fragments) throws Exception
+    public synchronized void attachFragments(List<Module> fragments) throws Exception
     {
         // Remove module from old fragment dependencies.
         // We will generally only remove module fragment
         // dependencies when we are uninstalling the module.
-        for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+        for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
         {
-            ((ModuleImpl) m_fragments[i]).removeDependentHost(this);
+            ((ModuleImpl) m_fragments.get(i)).removeDependentHost(this);
         }
 
         // Remove cached capabilities and requirements.
@@ -1185,12 +1142,12 @@
         // to attach to our content loader.
         if (m_fragments != null)
         {
-            IContent[] fragmentContents = new IContent[m_fragments.length];
-            for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+            Content[] fragmentContents = new Content[m_fragments.size()];
+            for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
             {
-                ((ModuleImpl) m_fragments[i]).addDependentHost(this);
+                ((ModuleImpl) m_fragments.get(i)).addDependentHost(this);
                 fragmentContents[i] =
-                    m_fragments[i].getContent()
+                    m_fragments.get(i).getContent()
                         .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
             }
             // Now attach the fragment contents to our content loader.
@@ -1199,7 +1156,7 @@
     }
 
     // This must be called holding the object lock.
-    private void attachFragmentContents(IContent[] fragmentContents)
+    private void attachFragmentContents(Content[] fragmentContents)
         throws Exception
     {
         // Close existing fragment contents.
@@ -1222,123 +1179,70 @@
         m_contentPath = initializeContentPath();
     }
 
-    public synchronized IModule[] getDependentHosts()
+    public synchronized List<Module> getDependentHosts()
     {
         return m_dependentHosts;
     }
 
-    public synchronized void addDependentHost(IModule module)
+    public synchronized void addDependentHost(Module module)
     {
-        m_dependentHosts = addDependent(m_dependentHosts, module);
+        if (!m_dependentHosts.contains(module))
+        {
+            m_dependentHosts.add(module);
+        }
     }
 
-    public synchronized void removeDependentHost(IModule module)
+    public synchronized void removeDependentHost(Module module)
     {
-        m_dependentHosts = removeDependent(m_dependentHosts, module);
+        m_dependentHosts.remove(module);
     }
 
-    public synchronized IModule[] getDependentImporters()
+    public synchronized List<Module> getDependentImporters()
     {
         return m_dependentImporters;
     }
 
-    public synchronized void addDependentImporter(IModule module)
+    public synchronized void addDependentImporter(Module module)
     {
-        m_dependentImporters = addDependent(m_dependentImporters, module);
+        if (!m_dependentImporters.contains(module))
+        {
+            m_dependentImporters.add(module);
+        }
     }
 
-    public synchronized void removeDependentImporter(IModule module)
+    public synchronized void removeDependentImporter(Module module)
     {
-        m_dependentImporters = removeDependent(m_dependentImporters, module);
+        m_dependentImporters.remove(module);
     }
 
-    public synchronized IModule[] getDependentRequirers()
+    public synchronized List<Module> getDependentRequirers()
     {
         return m_dependentRequirers;
     }
 
-    public synchronized void addDependentRequirer(IModule module)
+    public synchronized void addDependentRequirer(Module module)
     {
-        m_dependentRequirers = addDependent(m_dependentRequirers, module);
+        if (!m_dependentRequirers.contains(module))
+        {
+            m_dependentRequirers.add(module);
+        }
     }
 
-    public synchronized void removeDependentRequirer(IModule module)
+    public synchronized void removeDependentRequirer(Module module)
     {
-        m_dependentRequirers = removeDependent(m_dependentRequirers, module);
+        m_dependentRequirers.remove(module);
     }
 
-    public synchronized IModule[] getDependents()
+    public synchronized List<Module> getDependents()
     {
-        IModule[] dependents = new IModule[
-            m_dependentHosts.length + m_dependentImporters.length + m_dependentRequirers.length];
-        System.arraycopy(
-            m_dependentHosts,
-            0,
-            dependents,
-            0,
-            m_dependentHosts.length);
-        System.arraycopy(
-            m_dependentImporters,
-            0,
-            dependents,
-            m_dependentHosts.length,
-            m_dependentImporters.length);
-        System.arraycopy(
-            m_dependentRequirers,
-            0,
-            dependents,
-            m_dependentHosts.length + m_dependentImporters.length,
-            m_dependentRequirers.length);
+        List<Module> dependents = new ArrayList<Module>
+            (m_dependentHosts.size() + m_dependentImporters.size() + m_dependentRequirers.size());
+        dependents.addAll(m_dependentHosts);
+        dependents.addAll(m_dependentImporters);
+        dependents.addAll(m_dependentRequirers);
         return dependents;
     }
 
-    private static IModule[] addDependent(IModule[] modules, IModule module)
-    {
-        // Make sure the dependent module is not already present.
-        for (int i = 0; i < modules.length; i++)
-        {
-            if (modules[i].equals(module))
-            {
-                return modules;
-            }
-        }
-        IModule[] tmp = new IModule[modules.length + 1];
-        System.arraycopy(modules, 0, tmp, 0, modules.length);
-        tmp[modules.length] = module;
-        return tmp;
-    }
-
-    private static IModule[] removeDependent(IModule[] modules, IModule module)
-    {
-        IModule[] tmp = modules;
-
-        // Make sure the dependent module is present.
-        for (int i = 0; i < modules.length; i++)
-        {
-            if (modules[i].equals(module))
-            {
-                // If this is the module, then point to empty list.
-                if ((modules.length - 1) == 0)
-                {
-                    tmp = new IModule[0];
-                }
-                // Otherwise, we need to do some array copying.
-                else
-                {
-                    tmp = new IModule[modules.length - 1];
-                    System.arraycopy(modules, 0, tmp, 0, i);
-                    if (i < tmp.length)
-                    {
-                        System.arraycopy(modules, i + 1, tmp, i, tmp.length - i);
-                    }
-                }
-                break;
-            }
-        }
-
-        return tmp;
-    }
-
     public synchronized void close()
     {
         m_content.close();
@@ -1433,13 +1337,13 @@
         throws ClassNotFoundException, ResourceNotFoundException
     {
         // We delegate to the module's wires to find the class or resource.
-        IWire[] wires = getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
+        List<Wire> wires = getWires();
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
             // If we find the class or resource, then return it.
             Object result = (isClass)
-                ? (Object) wires[i].getClass(name)
-                : (Object) wires[i].getResource(name);
+                ? (Object) wires.get(i).getClass(name)
+                : (Object) wires.get(i).getResource(name);
             if (result != null)
             {
                 return result;
@@ -1456,10 +1360,10 @@
         // At this point, the module's imports were searched and so was the
         // the module's content. Now we make an attempt to load the
         // class/resource via a dynamic import, if possible.
-        IWire wire = null;
+        Wire wire = null;
         try
         {
-            wire = m_resolver.resolveDynamicImport(this, pkgName);
+            wire = m_resolver.resolve(this, pkgName);
         }
         catch (ResolveException ex)
         {
@@ -1772,8 +1676,8 @@
                 byte[] bytes = null;
 
                 // Check the module class path.
-                IContent[] contentPath = getContentPath();
-                IContent content = null;
+                Content[] contentPath = getContentPath();
+                Content content = null;
                 for (int i = 0;
                     (bytes == null) &&
                     (i < contentPath.length); i++)
@@ -1799,7 +1703,7 @@
                             int activationPolicy = 
                                 ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
                                 ? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
-                                : IModule.EAGER_ACTIVATION;
+                                : Module.EAGER_ACTIVATION;
 
                             // If the module is using deferred activation, then if
                             // we load this class from this module we need to activate
@@ -1810,7 +1714,7 @@
                                 ? false : isActivationTrigger(pkgName);
                             if (!m_isActivationTriggered
                                 && isTriggerClass
-                                && (activationPolicy == IModule.LAZY_ACTIVATION)
+                                && (activationPolicy == Module.LAZY_ACTIVATION)
                                 && (getBundle().getState() == Bundle.STARTING))
                             {
                                 List deferredList = (List) m_deferredActivation.get();
@@ -2027,14 +1931,14 @@
                 // native library.
                 if (result == null)
                 {
-                    R4Library[] libs = getNativeLibraries();
-                    for (int libIdx = 0; (libs != null) && (libIdx < libs.length); libIdx++)
+                    List<R4Library> libs = getNativeLibraries();
+                    for (int libIdx = 0; (libs != null) && (libIdx < libs.size()); libIdx++)
                     {
-                        if (libs[libIdx].match(m_configMap, name))
+                        if (libs.get(libIdx).match(m_configMap, name))
                         {
                             // Search bundle content first for native library.
                             result = getContent().getEntryAsNativeLibrary(
-                                libs[libIdx].getEntryName());
+                                libs.get(libIdx).getEntryName());
                             // If not found, then search fragments in order.
                             for (int i = 0;
                                 (result == null) && (m_fragmentContents != null)
@@ -2042,7 +1946,7 @@
                                 i++)
                             {
                                 result = m_fragmentContents[i].getEntryAsNativeLibrary(
-                                    libs[libIdx].getEntryName());
+                                    libs.get(libIdx).getEntryName());
                             }
                         }
                     }
@@ -2084,13 +1988,13 @@
         String importer = module.getBundle().toString();
 
         // Next, check to see if the module imports the package.
-        IWire[] wires = module.getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
+        List<Wire> wires = module.getWires();
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
-            if (wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-                wires[i].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
+            if (wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+                wires.get(i).getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
             {
-                String exporter = wires[i].getExporter().getBundle().toString();
+                String exporter = wires.get(i).getExporter().getBundle().toString();
 
                 StringBuffer sb = new StringBuffer("*** Package '");
                 sb.append(pkgName);
@@ -2114,7 +2018,7 @@
 
         // Next, check to see if the package was optionally imported and
         // whether or not there is an exporter available.
-        IRequirement[] reqs = module.getRequirements();
+        List<Requirement> reqs = module.getRequirements();
 /*
 * TODO: RB - Fix diagnostic message for optional imports.
         for (int i = 0; (reqs != null) && (i < reqs.length); i++)
@@ -2174,7 +2078,9 @@
         }
 */
         // Next, check to see if the package is dynamically imported by the module.
-        IRequirement pkgReq = Resolver.findAllowedDynamicImport(module, pkgName);
+// TODO: FELIX3 - Add Resolver.findAllowedDynamicImport().
+/*
+        Requirement pkgReq = Resolver.findAllowedDynamicImport(module, pkgName);
         if (pkgReq != null)
         {
             // Try to see if there is an exporter available.
@@ -2228,22 +2134,14 @@
 
             return sb.toString();
         }
-
+*/
         // Next, check to see if there are any exporters for the package at all.
-        pkgReq = null;
-        try
-        {
-            pkgReq = new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
-        }
-        catch (InvalidSyntaxException ex)
-        {
-            // This should never happen.
-        }
-        List exports =
-            resolver.getResolvedCandidates(pkgReq, module);
-        exports = (exports.size() == 0)
-            ? resolver.getUnresolvedCandidates(pkgReq, module)
-            : exports;
+        Requirement pkgReq = null;
+        List<Attribute> attrs = new ArrayList(1);
+        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+        pkgReq = new RequirementImpl(
+            Capability.PACKAGE_NAMESPACE, new ArrayList<Directive>(0), attrs);
+        Set<Capability> exports = resolver.getCandidates(module, pkgReq, false);
         if (exports.size() > 0)
         {
             boolean classpath = false;
@@ -2261,7 +2159,7 @@
                 // Ignore
             }
 
-            String exporter = ((ICapability) exports.get(0)).getModule().getBundle().toString();
+            String exporter = exports.iterator().next().getModule().getBundle().toString();
 
             StringBuffer sb = new StringBuffer("*** Class '");
             sb.append(name);
@@ -2345,4 +2243,46 @@
 
         return sb.toString();
     }
-}
+
+    static class FragmentRequirement implements Requirement
+    {
+        private final Requirement m_req;
+        private final Module m_fragment;
+
+        public FragmentRequirement(Requirement req, Module fragment)
+        {
+            m_req = req;
+            m_fragment = fragment;
+        }
+
+        public Module getFragment()
+        {
+            return m_fragment;
+        }
+
+        public String getNamespace()
+        {
+            return m_req.getNamespace();
+        }
+
+        public SimpleFilter getFilter()
+        {
+            return m_req.getFilter();
+        }
+
+        public boolean isOptional()
+        {
+            return m_req.isOptional();
+        }
+
+        public Directive getDirective(String name)
+        {
+            return m_req.getDirective(name);
+        }
+
+        public List<Directive> getDirectives()
+        {
+            return m_req.getDirectives();
+        }
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
new file mode 100644
index 0000000..04edb93
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -0,0 +1,499 @@
+/*
+ *  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.capabilityset;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class CapabilitySet
+{
+    private final Map<String, Map<Object, Set<Capability>>> m_indices =
+        new HashMap<String, Map<Object, Set<Capability>>>();
+    private final Set<Capability> m_capList = new HashSet<Capability>();
+
+    public CapabilitySet(List<String> indexProps)
+    {
+        for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
+        {
+            m_indices.put(indexProps.get(i), new HashMap<Object, Set<Capability>>());
+        }
+    }
+
+    public void addCapability(Capability cap)
+    {
+        m_capList.add(cap);
+
+        // Index capability.
+        for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+        {
+            Attribute capAttr = cap.getAttribute(entry.getKey());
+            if (capAttr != null)
+            {
+                Object capValue = capAttr.getValue();
+                if (capValue.getClass().isArray())
+                {
+                    capValue = convertArrayToList(capValue);
+                }
+
+                Map<Object, Set<Capability>> index = entry.getValue();
+
+                if (capValue instanceof Collection)
+                {
+                    Collection c = (Collection) capValue;
+                    for (Object o : c)
+                    {
+                        indexCapability(index, cap, o);
+                    }
+                }
+                else
+                {
+                    indexCapability(index, cap, capValue);
+                }
+            }
+        }
+
+//        System.out.println("+++ INDICES " + m_indices);
+    }
+
+    private void indexCapability(
+        Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+    {
+        Set<Capability> caps = index.get(capValue);
+        if (caps == null)
+        {
+            caps = new HashSet<Capability>();
+            index.put(capValue, caps);
+        }
+        caps.add(cap);
+    }
+
+    public void removeCapability(Capability cap)
+    {
+        if (m_capList.remove(cap))
+        {
+            for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+            {
+                Attribute capAttr = cap.getAttribute(entry.getKey());
+                if (capAttr != null)
+                {
+                    Object capValue = capAttr.getValue();
+                    if (capValue.getClass().isArray())
+                    {
+                        capValue = convertArrayToList(capValue);
+                    }
+
+                    Map<Object, Set<Capability>> index = entry.getValue();
+
+                    if (capValue instanceof Collection)
+                    {
+                        Collection c = (Collection) capValue;
+                        for (Object o : c)
+                        {
+                            deindexCapability(index, cap, o);
+                        }
+                    }
+                    else
+                    {
+                        deindexCapability(index, cap, capValue);
+                    }
+                }
+            }
+
+//            System.out.println("+++ INDICES " + m_indices);
+        }
+    }
+
+    private void deindexCapability(
+        Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+    {
+        Set<Capability> caps = index.get(capValue);
+        caps.remove(cap);
+        if (caps.size() == 0)
+        {
+            index.remove(capValue);
+        }
+    }
+
+    public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
+    {
+        Set<Capability> matches = match(m_capList, sf);
+        return (obeyMandatory)
+            ? matchMandatory(matches, sf)
+            : matches;
+    }
+
+    private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
+    {
+//System.out.println("+++ SF " + sf);
+        Set<Capability> matches = new HashSet<Capability>();
+
+        if (sf.getOperation() == SimpleFilter.AND)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For AND we calculate the intersection of each subfilter.
+            // We can short-circuit the AND operation if there are no
+            // remaining capabilities.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
+            {
+//System.out.println("+++ REMAINING " + caps);
+                matches = match(caps, sfs.get(i));
+//System.out.println("+++ CURRENT " + matches);
+                caps = matches;
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.OR)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matches.addAll(match(caps, sfs.get(i)));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.NOT)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            matches.addAll(caps);
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matches.removeAll(match(caps, sfs.get(i)));
+            }
+        }
+        else
+        {
+            Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
+            if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
+            {
+                Set<Capability> existingCaps = index.get(sf.getValue());
+                if (existingCaps != null)
+                {
+                    matches.addAll(existingCaps);
+//System.out.println("NARROWED " + caps.size() + " TO " + existingCaps.size());
+                    matches.retainAll(caps);
+                }
+            }
+            else
+            {
+//                System.out.println("+++ SEARCHING " + caps.size() + " CAPABILITIES");
+                for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+                {
+                    Capability cap = it.next();
+                    Attribute attr = cap.getAttribute(sf.getName());
+                    if (attr != null)
+                    {
+                        Object lhs = attr.getValue();
+                        if (compare(lhs, sf.getValue(), sf.getOperation()))
+                        {
+                            matches.add(cap);
+                        }
+                    }
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    public static boolean matches(Capability cap, SimpleFilter sf)
+    {
+        return matchesInternal(cap, sf) && matchMandatory(cap, sf);
+    }
+
+    private static boolean matchesInternal(Capability cap, SimpleFilter sf)
+    {
+        boolean matched = true;
+
+        if (sf.getOperation() == SimpleFilter.AND)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For AND we calculate the intersection of each subfilter.
+            // We can short-circuit the AND operation if there are no
+            // remaining capabilities.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; matched && (i < sfs.size()); i++)
+            {
+                matched = matchesInternal(cap, sfs.get(i));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.OR)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            matched = false;
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; !matched && (i < sfs.size()); i++)
+            {
+                matched = matchesInternal(cap, sfs.get(i));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.NOT)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matched = !(matchesInternal(cap, sfs.get(i)));
+            }
+        }
+        else
+        {
+            matched = false;
+            Attribute attr = cap.getAttribute(sf.getName());
+            if (attr != null)
+            {
+                Object lhs = attr.getValue();
+                matched = compare(lhs, sf.getValue(), sf.getOperation());
+            }
+        }
+
+        return matched;
+    }
+
+    private static Set<Capability> matchMandatory(Set<Capability> caps, SimpleFilter sf)
+    {
+        for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+        {
+            Capability cap = it.next();
+            if (!matchMandatory(cap, sf))
+            {
+                it.remove();
+            }
+        }
+        return caps;
+    }
+
+    private static boolean matchMandatory(Capability cap, SimpleFilter sf)
+    {
+        List<Attribute> attrs = cap.getAttributes();
+        for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+        {
+            if (attrs.get(attrIdx).isMandatory()
+                && !matchMandatory(attrs.get(attrIdx), sf))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean matchMandatory(Attribute attr, SimpleFilter sf)
+    {
+        if ((sf.getName() != null) && sf.getName().equals(attr.getName()))
+        {
+            return true;
+        }
+        else if (sf.getOperation() == SimpleFilter.AND)
+        {
+            List list = (List) sf.getValue();
+            for (int i = 0; i < list.size(); i++)
+            {
+                SimpleFilter sf2 = (SimpleFilter) list.get(i);
+                if ((sf2.getName() != null)
+                    && sf2.getName().equals(attr.getName()))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static final Class[] STRING_CLASS = new Class[] { String.class };
+
+    private static boolean compare(Object lhs, Object rhsUnknown, int op)
+    {
+        // If the type is comparable, then we can just return the
+        // result immediately.
+        if (lhs instanceof Comparable)
+        {
+            // The substring operator only works on string values, so if the
+            // lhs is not a string, then do an equality comparison using the
+            // original string containing wildcards.
+            if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+            {
+                op = SimpleFilter.EQ;
+                rhsUnknown = SimpleFilter.unparseSubstring((List<String>) rhsUnknown);
+            }
+
+            Object rhs;
+            if (op == SimpleFilter.SUBSTRING)
+            {
+                rhs = rhsUnknown;
+            }
+            else
+            {
+                try
+                {
+                    rhs = coerceType(lhs, (String) rhsUnknown);
+                }
+                catch (Exception ex)
+                {
+                    return false;
+                }
+            }
+
+            switch (op)
+            {
+                case SimpleFilter.EQ :
+                    return (((Comparable) lhs).compareTo(rhs) == 0);
+                case SimpleFilter.GTE :
+                    return (((Comparable) lhs).compareTo(rhs) >= 0);
+                case SimpleFilter.LTE :
+                    return (((Comparable) lhs).compareTo(rhs) <= 0);
+//                case SimpleFilter.APPROX :
+//                    return compareToApprox(((Comparable) lhs), rhs);
+                case SimpleFilter.SUBSTRING :
+                    return SimpleFilter.compareSubstring((String) lhs, (List<String>) rhs);
+                default:
+                    throw new RuntimeException(
+                        "Unknown comparison operator: " + op);
+            }
+        }
+        // Booleans do not implement comparable, so special case them.
+        else if (lhs instanceof Boolean)
+        {
+            Object rhs;
+            try
+            {
+                rhs = coerceType(lhs, (String) rhsUnknown);
+            }
+            catch (Exception ex)
+            {
+                return false;
+            }
+
+            switch (op)
+            {
+                case SimpleFilter.EQ :
+                case SimpleFilter.GTE :
+                case SimpleFilter.LTE :
+//                case SimpleFilter.APPROX:
+                    return (lhs.equals(rhs));
+                default:
+                    throw new RuntimeException(
+                        "Unknown comparison operator: " + op);
+            }
+        }
+
+        // If the LHS is not a comparable or boolean, check if it is an
+        // array. If so, convert it to a list so we can treat it as a
+        // collection.
+        if (lhs.getClass().isArray())
+        {
+            lhs = convertArrayToList(lhs);
+        }
+
+        // If LHS is a collection, then call compare() on each element
+        // of the collection until a match is found.
+        if (lhs instanceof Collection)
+        {
+            for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); )
+            {
+                if (compare(iter.next(), rhsUnknown, op))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        // Since we cannot identify the LHS type, then we can only perform
+        // equality comparison.
+        try
+        {
+            return lhs.equals(coerceType(lhs, (String) rhsUnknown));
+        }
+        catch (Exception ex)
+        {
+            return false;
+        }
+    }
+
+    private static Object coerceType(Object lhs, String rhsString) throws Exception
+    {
+        // If the LHS expects a string, then we can just return
+        // the RHS since it is a string.
+        if (lhs.getClass() == rhsString.getClass())
+        {
+            return rhsString;
+        }
+
+        // Try to convert the RHS type to the LHS type by using
+        // the string constructor of the LHS class, if it has one.
+        Object rhs = null;
+        try
+        {
+            // The Character class is a special case, since its constructor
+            // does not take a string, so handle it separately.
+            if (lhs instanceof Character)
+            {
+                rhs = new Character(rhsString.charAt(0));
+            }
+            else
+            {
+                rhs = lhs.getClass()
+                    .getConstructor(STRING_CLASS)
+                        .newInstance(new Object[] { rhsString });
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new Exception(
+                "Could not instantiate class "
+                    + lhs.getClass().getName()
+                    + " from string constructor with argument '"
+                    + rhsString + "' because " + ex);
+        }
+
+        return rhs;
+    }
+
+    /**
+     * This is an ugly utility method to convert an array of primitives
+     * to an array of primitive wrapper objects. This method simplifies
+     * processing LDAP filters since the special case of primitive arrays
+     * can be ignored.
+     * @param array An array of primitive types.
+     * @return An corresponding array using pritive wrapper objects.
+    **/
+    private static List convertArrayToList(Object array)
+    {
+        int len = Array.getLength(array);
+        List list = new ArrayList(len);
+        for (int i = 0; i < len; i++)
+        {
+            list.add(Array.get(array, i));
+        }
+        return list;
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
new file mode 100644
index 0000000..b72ea49
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
@@ -0,0 +1,103 @@
+/*
+ *  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.Comparator;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+public class CandidateComparator implements Comparator
+{
+    public int compare(Object arg1, Object arg2)
+    {
+        Capability cap1 = (Capability) arg1;
+        Capability cap2 = (Capability) arg2;
+
+        // First check resolved state, since resolved capabilities have priority
+        // over unresolved ones. Compare in reverse order since we want to sort
+        // in descending order.
+        int c = 0;
+        if (cap1.getModule().isResolved() && !cap2.getModule().isResolved())
+        {
+            c = -1;
+        }
+        else if (!cap1.getModule().isResolved() && cap2.getModule().isResolved())
+        {
+            c = 1;
+        }
+
+        // Next compare version numbers.
+        if ((c == 0) && cap1.getNamespace().equals(Capability.MODULE_NAMESPACE))
+        {
+            c = ((Comparable) cap1.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+                .getValue()).compareTo(cap2.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+                    .getValue());
+            if (c == 0)
+            {
+                Version v1 = (cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+                    ? Version.emptyVersion
+                    : (Version) cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
+                Version v2 = (cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+                    ? Version.emptyVersion
+                    : (Version) cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
+                // Compare these in reverse order, since we want
+                // highest version to have priority.
+                c = v2.compareTo(v1);
+            }
+        }
+// TODO: PROTO3 RESOLVER - Need to change this to handle arbitrary capabilities
+//       that may not have a natural ordering.
+        // Assume everything else is a package capability.
+        else if (c == 0)
+        {
+            c = ((Comparable) cap1.getAttribute(Capability.PACKAGE_ATTR).getValue())
+                .compareTo(cap2.getAttribute(Capability.PACKAGE_ATTR).getValue());
+            if (c == 0)
+            {
+                Version v1 = (cap1.getAttribute(Capability.VERSION_ATTR) == null)
+                    ? Version.emptyVersion
+                    : (Version) cap1.getAttribute(Capability.VERSION_ATTR).getValue();
+                Version v2 = (cap2.getAttribute(Capability.VERSION_ATTR) == null)
+                    ? Version.emptyVersion
+                    : (Version) cap2.getAttribute(Capability.VERSION_ATTR).getValue();
+                // Compare these in reverse order, since we want
+                // highest version to have priority.
+                c = v2.compareTo(v1);
+            }
+        }
+
+        // Finally, compare module identity.
+        if (c == 0)
+        {
+            if (cap1.getModule().getBundle().getBundleId() <
+                cap2.getModule().getBundle().getBundleId())
+            {
+                c = -1;
+            }
+            else if (cap1.getModule().getBundle().getBundleId() >
+                cap2.getModule().getBundle().getBundleId())
+            {
+                c = 1;
+            }
+        }
+
+        return c;
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Content.java b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
new file mode 100644
index 0000000..3e13a19
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
@@ -0,0 +1,112 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+public interface Content
+{
+    /**
+     * <p>
+     * This method must be called when the content is no longer needed so
+     * that any resourses being used (e.g., open files) can be closed. Once
+     * this method is called, the content is no longer usable. If the content
+     * is already closed, then calls on this method should have no effect.
+     * </p>
+    **/
+    void close();
+
+    /**
+     * <p>
+     * This method determines if the specified named entry is contained in
+     * the associated content. The entry name is a relative path with '/'
+     * separators.
+     * </p>
+     * @param name The name of the entry to find.
+     * @return <tt>true</tt> if a corresponding entry was found, <tt>false</tt>
+     *         otherwise.
+    **/
+    boolean hasEntry(String name);
+
+    /**
+     * <p>
+     * Returns an enumeration of entry names as <tt>String</tt> objects.
+     * An entry name is a path constructed with '/' as path element
+     * separators and is relative to the root of the content. Entry names
+     * for entries that represent directories should end with the '/'
+     * character.
+     * </p>
+     * @returns An enumeration of entry names or <tt>null</tt>.
+    **/
+    Enumeration getEntries();
+
+    /**
+     * <p>
+     * This method returns the named entry as an array of bytes.
+     * </p>
+     * @param name The name of the entry to retrieve as a byte array.
+     * @return An array of bytes if the corresponding entry was found, <tt>null</tt>
+     *         otherwise.
+    **/
+    byte[] getEntryAsBytes(String name);
+
+    /**
+     * <p>
+     * This method returns the named entry as an input stream.
+     * </p>
+     * @param name The name of the entry to retrieve as an input stream.
+     * @return An input stream if the corresponding entry was found, <tt>null</tt>
+     *         otherwise.
+     * @throws <tt>java.io.IOException</tt> if any error occurs.
+    **/
+    InputStream getEntryAsStream(String name) throws IOException;
+
+    /**
+     * <p>
+     * This method returns the named entry as an <tt>IContent</tt> Typically,
+     * this method only makes sense for entries that correspond to some form
+     * of aggregated resource (e.g., an embedded JAR file or directory), but
+     * implementations are free to interpret this however makes sense. This method
+     * should return a new <tt>IContent</tt> instance for every invocation and
+     * the caller is responsible for opening and closing the returned content
+     * object.
+     * </p>
+     * @param name The name of the entry to retrieve as an <tt>IContent</tt>.
+     * @return An <tt>IContent</tt> instance if a corresponding entry was found,
+     *         <tt>null</tt> otherwise.
+    **/
+    Content getEntryAsContent(String name);
+
+    /**
+     * <p>
+     * This method returns the named entry as a file in the file system for
+     * use as a native library. It may not be possible for all content
+     * implementations (e.g., memory only) to implement this method, in which
+     * case it is acceptable to return <tt>null</tt>. Since native libraries
+     * can only be associated with a single class loader, this method should
+     * return a unique file per request.
+     * </p>
+     * @param name The name of the entry to retrieve as a file.
+     * @return A string corresponding to the absolute path of the file if a
+     *         corresponding entry was found, <tt>null</tt> otherwise.
+    **/
+    String getEntryAsNativeLibrary(String name);
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
new file mode 100644
index 0000000..25258e9
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
@@ -0,0 +1,77 @@
+/*
+ *  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.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+public interface Module
+{
+    final static int EAGER_ACTIVATION = 0;
+    final static int LAZY_ACTIVATION = 1;
+
+    // Metadata access methods.
+    Map getHeaders();
+    boolean isExtension();
+    String getSymbolicName();
+    Version getVersion();
+    List<Capability> getCapabilities();
+    List<Requirement> getRequirements();
+    List<Requirement> getDynamicRequirements();
+    List<R4Library> getNativeLibraries();
+    int getDeclaredActivationPolicy();
+
+    // Run-time data access methods.
+    Bundle getBundle();
+    String getId();
+    List<Wire> getWires();
+    boolean isResolved();
+    // TODO: FELIX3 - Shouldn't have mutable method on Module.
+    void setSecurityContext(Object securityContext);
+    Object getSecurityContext();
+
+    // Content access methods.
+    Content getContent();
+    Class getClassByDelegation(String name) throws ClassNotFoundException;
+    URL getResourceByDelegation(String name);
+    Enumeration getResourcesByDelegation(String name);
+    URL getEntry(String name);
+
+    // TODO: ML - For expediency, the index argument was added to these methods
+    // but it is not clear that this makes sense in the long run. This needs to
+    // be readdressed in the future, perhaps by the spec to clearly indicate
+    // how resources on the bundle class path are searched, which is why we
+    // need the index number in the first place -- to differentiate among
+    // resources with the same name on the bundle class path. This was previously
+    // handled as part of the resource path, but that approach is not spec
+    // compliant.
+    boolean hasInputStream(int index, String urlPath)
+        throws IOException;
+    InputStream getInputStream(int index, String urlPath)
+        throws IOException;
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
new file mode 100755
index 0000000..e790856
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.felix.framework.resolver;
+
+import org.apache.felix.framework.capabilityset.Requirement;
+
+public class ResolveException extends RuntimeException
+{
+    private final Module m_module;
+    private final Requirement m_req;
+
+    /**
+     * Constructs an instance of <code>ResolveException</code> with the specified detail message.
+     * @param msg the detail message.
+     */
+    public ResolveException(String msg, Module module, Requirement req)
+    {
+        super(msg);
+        m_module = module;
+        m_req = req;
+    }
+
+    public Module getModule()
+    {
+        return m_module;
+    }
+
+    public Requirement getRequirement()
+    {
+        return m_req;
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..c8bd513
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.felix.framework.resolver;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+
+public interface Resolver
+{
+    Map<Module, List<Wire>> resolve(ResolverState state, Module module);
+    Map<Module, List<Wire>> resolve(ResolverState state, Module module, String pkgName);
+
+    public static interface ResolverState
+    {
+        Set<Capability> getCandidates(Module module, Requirement req, boolean obeyMandatory);
+    }
+}
\ 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
new file mode 100644
index 0000000..1a90baa
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -0,0 +1,1581 @@
+/*
+ *  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.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import org.apache.felix.framework.FelixResolverState;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.util.manifestparser.RequirementImpl;
+import org.osgi.framework.Constants;
+
+// 1. Treat hard pkg constraints separately from implied package constraints
+// 2. Map pkg constraints to a set of capabilities, not a single capability.
+// 3. Uses constraints cannot conflict with other uses constraints, only with hard constraints.
+public class ResolverImpl implements Resolver
+{
+    private final Logger m_logger;
+
+    // Execution environment.
+// TODO: FELIX3 - Move EE checking to ResolverState interface.
+    private final String m_fwkExecEnvStr;
+    private final Set m_fwkExecEnvSet;
+
+    private static final Map<String, Long> m_invokeCounts = new HashMap<String, Long>();
+    private static boolean m_isInvokeCount = false;
+
+    // Reusable empty array.
+    private static final List<Wire> m_emptyWires = new ArrayList<Wire>(0);
+
+    public ResolverImpl(Logger logger, String fwkExecEnvStr)
+    {
+System.out.println("+++ PROTO3 RESOLVER");
+        m_logger = logger;
+        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
+        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
+
+        String v = System.getProperty("invoke.count");
+        m_isInvokeCount = (v == null) ? false : Boolean.valueOf(v);
+    }
+
+    private final List<Map<Requirement, Set<Capability>>> m_candidatePermutations =
+        new ArrayList<Map<Requirement, Set<Capability>>>();
+
+    public Map<Module, List<Wire>> resolve(ResolverState state, Module module)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+
+        Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
+
+        if (!module.isResolved())
+        {
+            m_candidatePermutations.clear();
+
+//System.out.println("+++ RESOLVING " + module);
+            Map<Requirement, Set<Capability>> candidateMap =
+                new HashMap<Requirement, Set<Capability>>();
+
+            populateCandidates(state, module, m_fwkExecEnvStr, m_fwkExecEnvSet,
+                candidateMap, new HashMap<Module, Object>());
+            m_candidatePermutations.add(candidateMap);
+
+            ResolveException rethrow = null;
+
+            do
+            {
+                rethrow = null;
+
+                candidateMap = m_candidatePermutations.remove(0);
+//dumpCandidateMap(state, candidateMap);
+
+                try
+                {
+                    findConsistentCandidates(
+                        module,
+                        new ArrayList(),
+                        candidateMap,
+                        modulePkgMap,
+                        new HashMap<Module, Object>());
+                }
+                catch (ResolveException ex)
+                {
+                    rethrow = ex;
+                    System.out.println("RE: " + ex);
+                }
+            }
+            while ((rethrow != null) && (m_candidatePermutations.size() > 0));
+
+            if (rethrow != null)
+            {
+                throw rethrow;
+            }
+//dumpModulePkgMap(modulePkgMap);
+
+            wireMap =
+                populateWireMap(module, modulePkgMap, wireMap,
+                candidateMap);
+        }
+
+        if (m_isInvokeCount)
+        {
+            System.out.println("INVOKE COUNTS " + m_invokeCounts);
+        }
+
+        return wireMap;
+    }
+
+    public Map<Module, List<Wire>> resolve(ResolverState state, Module module, String pkgName)
+    {
+        Capability candidate = null;
+
+        // We can only create a dynamic import if the following
+        // conditions are met:
+        // 1. The specified module is resolved.
+        // 2. The package in question is not already imported.
+        // 3. The package in question is not accessible via require-bundle.
+        // 4. The package in question is not exported by the bundle.
+        // 5. The package in question matches a dynamic import of the bundle.
+        // The following call checks all of these conditions and returns
+        // a matching dynamic requirement if possible.
+        Map<Requirement, Set<Capability>> candidateMap =
+            new HashMap<Requirement, Set<Capability>>();
+        if (isAllowedDynamicImport(state, module, pkgName, candidateMap))
+        {
+            m_candidatePermutations.clear();
+
+            Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+
+            Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
+
+//System.out.println("+++ DYNAMICALLY RESOLVING " + module + " - " + pkgName);
+            populateDynamicCandidates(state, module,
+                m_fwkExecEnvStr, m_fwkExecEnvSet, candidateMap);
+            m_candidatePermutations.add(candidateMap);
+            ResolveException rethrow = null;
+
+            do
+            {
+                rethrow = null;
+
+                candidateMap = m_candidatePermutations.remove(0);
+//dumpCandidateMap(state, candidateMap);
+
+                try
+                {
+                    findConsistentDynamicCandidate(
+                        module,
+                        new ArrayList(),
+                        candidateMap,
+                        modulePkgMap);
+                }
+                catch (ResolveException ex)
+                {
+                    rethrow = ex;
+                    System.out.println("RE: " + ex);
+                }
+            }
+            while ((rethrow != null) && (m_candidatePermutations.size() > 0));
+
+            if (rethrow != null)
+            {
+                throw rethrow;
+            }
+//dumpModulePkgMap(modulePkgMap);
+            wireMap =
+                populateDynamicWireMap(
+                    module, pkgName, modulePkgMap, wireMap, candidateMap);
+
+//System.out.println("+++ DYNAMIC SUCCESS: " + wireMap.get(module));
+            return wireMap;
+        }
+
+//System.out.println("+++ DYNAMIC FAILURE");
+        return null;
+    }
+
+    // TODO: FELIX3 - It would be nice to make this private.
+    // TODO: FELIX3 - At a minimum, figure out a different way than passing in the
+    //       candidate map.
+    public static boolean isAllowedDynamicImport(
+        ResolverState state, Module module, String pkgName, Map<Requirement,
+        Set<Capability>> candidateMap)
+    {
+        // Unresolved modules cannot dynamically import, nor can the default
+        // package be dynamically imported.
+        if (!module.isResolved() || pkgName.length() == 0)
+        {
+            return false;
+        }
+
+        // If any of the module exports this package, then we cannot
+        // attempt to dynamically import it.
+        List<Capability> caps = module.getCapabilities();
+        for (int i = 0; (caps != null) && (i < caps.size()); i++)
+        {
+            if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                && caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+            {
+                return false;
+            }
+        }
+        // If any of our wires have this package, then we cannot
+        // attempt to dynamically import it.
+        List<Wire> wires = module.getWires();
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        {
+            if (wires.get(i).hasPackage(pkgName))
+            {
+                return false;
+            }
+        }
+
+        // Loop through the importer's dynamic requirements to determine if
+        // there is a matching one for the package from which we want to
+        // load a class.
+        List<Directive> dirs = new ArrayList(0);
+        List<Attribute> attrs = new ArrayList(1);
+        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+        Requirement req = new RequirementImpl(Capability.PACKAGE_NAMESPACE, dirs, attrs);
+        Set<Capability> candidates = state.getCandidates(module, req, false);
+        List<Requirement> dynamics = module.getDynamicRequirements();
+
+        // First find a dynamic requirement that matches the capabilities.
+        Requirement dynReq = null;
+        for (int dynIdx = 0;
+            (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
+            dynIdx++)
+        {
+            for (Iterator<Capability> itCand = candidates.iterator();
+                (dynReq == null) && itCand.hasNext(); )
+            {
+                Capability cap = itCand.next();
+                if (CapabilitySet.matches(cap, dynamics.get(dynIdx).getFilter()))
+                {
+                    dynReq = dynamics.get(dynIdx);
+                }
+            }
+        }
+
+        // If we found a matching dynamic requirement, then filter out
+        // any candidates that do not match it.
+        if (dynReq != null)
+        {
+            for (Iterator<Capability> itCand = candidates.iterator(); itCand.hasNext(); )
+            {
+                Capability cap = itCand.next();
+                if (!CapabilitySet.matches(cap, dynReq.getFilter()))
+                {
+                    itCand.remove();
+                }
+            }
+            
+            if (candidates.size() > 0)
+            {
+                candidateMap.put(dynReq, candidates);
+            }
+        }
+        else
+        {
+            candidates.clear();
+        }
+
+        return !candidates.isEmpty();
+    }
+
+    private static void dumpCandidateMap(
+        ResolverState state, Map<Requirement, Set<Capability>> candidateMap)
+    {
+        System.out.println("=== BEGIN CANDIDATE MAP ===");
+        for (Module module : ((FelixResolverState) state).getModules())
+        {
+            System.out.println("  " + module
+                 + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
+            for (Requirement req : module.getRequirements())
+            {
+                Set<Capability> candidates = candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+            for (Requirement req : module.getDynamicRequirements())
+            {
+                Set<Capability> candidates = candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+        }
+        System.out.println("=== END CANDIDATE MAP ===");
+    }
+
+    private static void dumpModulePkgMap(Map<Module, Packages> modulePkgMap)
+    {
+        System.out.println("+++MODULE PKG MAP+++");
+        for (Entry<Module, Packages> entry : modulePkgMap.entrySet())
+        {
+            dumpModulePkgs(entry.getKey(), entry.getValue());
+        }
+    }
+
+    private static void dumpModulePkgs(Module module, Packages packages)
+    {
+        System.out.println(module + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
+        System.out.println("  EXPORTED");
+        for (Entry<String, Blame> entry : packages.m_exportedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  IMPORTED");
+        for (Entry<String, Blame> entry : packages.m_importedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  REQUIRED");
+        for (Entry<String, List<Blame>> entry : packages.m_requiredPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  USED");
+        for (Entry<String, List<Blame>> entry : packages.m_usedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+    }
+
+    private static void populateCandidates(
+        ResolverState state, Module module, String fwkExecEnvStr, Set fwkExecEnvSet,
+        Map<Requirement, Set<Capability>> candidateMap, Map<Module, Object> resultCache)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        // Determine if we've already calculated this module's candidates.
+        // The result cache will have one of three values:
+        //   1. A resolve exception if we've already attempted to populate the
+        //      module's candidates but were unsuccessful.
+        //   2. Boolean.TRUE indicating we've already attempted to populate the
+        //      module's candidates and were successful.
+        //   3. An array containing the cycle count, current map of candidates
+        //      for already processed requirements, and a list of remaining
+        //      requirements whose candidates still need to be calculated.
+        // For case 1, rethrow the exception. For case 3, simply return immediately.
+        // For case 3, this means we have a cycle so we should continue to populate
+        // the candidate where we left off and not record any results globally
+        // until we've popped completely out of the cycle.
+
+        // Keeps track of the number of times we've reentered this method
+        // for the current module.
+        Integer cycleCount = null;
+
+        // Keeps track of the candidates we've already calculated for the
+        // current module's requirements.
+        Map<Requirement, Set<Capability>> localCandidateMap = null;
+
+        // Keeps track of the current module's requirements for which we
+        // haven't yet found candidates.
+        List<Requirement> remainingReqs = null;
+
+        // Get the cache value for the current module.
+        Object cacheValue = resultCache.get(module);
+
+        // This is case 1.
+        if (cacheValue instanceof ResolveException)
+        {
+            throw (ResolveException) cacheValue;
+        }
+        // This is case 2.
+        else if (cacheValue instanceof Boolean)
+        {
+            return;
+        }
+        // This is case 3.
+        else if (cacheValue != null)
+        {
+            cycleCount = (Integer) ((Object[]) cacheValue)[0];
+            ((Object[]) cacheValue)[0] = new Integer(cycleCount.intValue() + 1);
+            cycleCount = (Integer) ((Object[]) cacheValue)[0];
+            localCandidateMap = (Map) ((Object[]) cacheValue)[1];
+            remainingReqs = (List) ((Object[]) cacheValue)[2];
+        }
+
+        // If there is no cache value for the current module, then this is
+        // the first time we are attempting to populate its candidates, so
+        // do some one-time checks and initialization.
+        if ((remainingReqs == null) && (localCandidateMap == null))
+        {
+            // Verify that any required execution environment is satisfied.
+            verifyExecutionEnvironment(fwkExecEnvStr, fwkExecEnvSet, module);
+
+            // Verify that any native libraries match the current platform.
+            verifyNativeLibraries(module);
+
+            // Record cycle count.
+            cycleCount = new Integer(0);
+
+            // Store candidates in a local map first, just in case the module
+            // is not resolvable.
+            localCandidateMap = new HashMap();
+
+            // Create a modifiable list of the module's requirements.
+            remainingReqs = new ArrayList(module.getRequirements());
+
+            // Add these value to the result cache so we know we are
+            // in the middle of populating candidates for the current
+            // module.
+            resultCache.put(module,
+                cacheValue = new Object[] { cycleCount, localCandidateMap, remainingReqs });
+        }
+
+        // If we have requirements remaining, then find candidates for them.
+        while (remainingReqs.size() > 0)
+        {
+            Requirement req = remainingReqs.remove(0);
+
+            // Get satisfying candidates and populate their candidates if necessary.
+            Set<Capability> candidates = state.getCandidates(module, req, true);
+            for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
+            {
+                Capability candCap = itCandCap.next();
+                if (!candCap.getModule().isResolved())
+                {
+                    try
+                    {
+                        populateCandidates(state, candCap.getModule(),
+                            fwkExecEnvStr, fwkExecEnvSet, candidateMap, resultCache);
+                    }
+                    catch (ResolveException ex)
+                    {
+System.out.println("RE: Candidate not resolveable: " + ex);
+                        // Remove the candidate since we weren't able to
+                        // populate its candidates.
+                        itCandCap.remove();
+                    }
+                }
+            }
+
+            // If there are no candidates for the current requirement
+            // and it is not optional, then create, cache, and throw
+            // a resolve exception.
+            if ((candidates.size() == 0) && !req.isOptional())
+            {
+                ResolveException ex =
+                    new ResolveException("Unable to resolve " + module
+                        + ": missing requirement " + req, module, req);
+                resultCache.put(module, ex);
+                throw ex;
+            }
+            // If we actually have candidates for the requirement, then
+            // add them to the local candidate map.
+            else if (candidates.size() > 0)
+            {
+                localCandidateMap.put(req, candidates);
+            }
+        }
+
+        // If we are exiting from a cycle then decrement
+        // cycle counter, otherwise record the result.
+        if (cycleCount.intValue() > 0)
+        {
+            ((Object[]) cacheValue)[0] = new Integer(cycleCount.intValue() - 1);
+        }
+        else if (cycleCount.intValue() == 0)
+        {
+            // Record that the module was successfully populated.
+            resultCache.put(module, Boolean.TRUE);
+
+            // Merge local candidate map into global candidate map.
+            if (localCandidateMap.size() > 0)
+            {
+                candidateMap.putAll(localCandidateMap);
+            }
+        }
+    }
+
+    private static void populateDynamicCandidates(
+        ResolverState state, Module module,
+        String fwkExecEnvStr, Set fwkExecEnvSet,
+        Map<Requirement, Set<Capability>> candidateMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        // There should be one entry in the candidate map, which are the
+        // the candidates for the matching dynamic requirement. Get the
+        // matching candidates and populate their candidates if necessary.
+        Entry<Requirement, Set<Capability>> entry = candidateMap.entrySet().iterator().next();
+        Requirement dynReq = entry.getKey();
+        Set<Capability> candidates = entry.getValue();
+        for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
+        {
+            Capability candCap = itCandCap.next();
+            if (!candCap.getModule().isResolved())
+            {
+                try
+                {
+                    populateCandidates(state, candCap.getModule(),
+                        fwkExecEnvStr, fwkExecEnvSet, candidateMap,
+                        new HashMap<Module, Object>());
+                }
+                catch (ResolveException ex)
+                {
+System.out.println("RE: Candidate not resolveable: " + ex);
+                    itCandCap.remove();
+                }
+            }
+        }
+
+// TODO: FELIX3 - Since we reuse the same dynamic requirement, is it possible
+//       that some sort of cycle could cause us to try to match another set
+//       of candidates to the same requirement?
+        if (candidates.size() == 0)
+        {
+            candidateMap.remove(dynReq);
+            throw new ResolveException("Dynamic import failed.", module, dynReq);
+        }
+
+        // Add existing wires as candidates.
+        for (Wire wire : module.getWires())
+        {
+            Set<Capability> cs = new TreeSet();
+            cs.add(wire.getCapability());
+            candidateMap.put(wire.getRequirement(), cs);
+        }
+    }
+
+    private void findConsistentCandidates(
+        Module module, List<Requirement> incomingReqs,
+        Map<Requirement, Set<Capability>> candidateMap,
+        Map<Module, Packages> modulePkgMap,
+        Map<Module, Object> cycleMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        Integer cycleCount = null;
+
+        Object o = cycleMap.get(module);
+
+        if (o instanceof Boolean)
+        {
+            return;
+        }
+        else if (o == null)
+        {
+            List list;
+            if (module.isResolved())
+            {
+                list = new ArrayList(module.getWires());
+            }
+            else
+            {
+                list = new ArrayList(module.getRequirements());
+            }
+            cycleMap.put(module, o = new Object[] { cycleCount = new Integer(0), list });
+            calculateExportedPackages(module, incomingReqs, modulePkgMap);
+        }
+        else
+        {
+            cycleCount = (Integer) ((Object[]) o)[0];
+            ((Object[]) o)[0] = new Integer(cycleCount.intValue() + 1);
+            cycleCount = (Integer) ((Object[]) o)[0];
+        }
+
+//System.out.println("+++ RESOLVING " + module);
+
+        if (module.isResolved())
+        {
+            List<Wire> wires = (List<Wire>) ((Object[]) o)[1];
+
+            while (wires.size() > 0)
+            {
+                Wire wire = wires.remove(0);
+
+                // Try to resolve the candidate.
+                findConsistentCandidates(
+                    wire.getCapability().getModule(),
+                    incomingReqs,
+                    candidateMap,
+                    modulePkgMap,
+                    cycleMap);
+
+                // If we are here, the candidate was consistent. Try to
+                // merge the candidate into the target module's packages.
+                mergeCandidatePackages(
+                    module,
+                    incomingReqs,
+                    wire.getCapability(),
+                    modulePkgMap,
+                    candidateMap);
+            }
+        }
+        else
+        {
+            List<Requirement> reqs = (List<Requirement>) ((Object[]) o)[1];
+
+            while (reqs.size() > 0)
+            {
+                Requirement req = reqs.remove(0);
+
+                // Get the candidates for the current requirement.
+                Set<Capability> candCaps = candidateMap.get(req);
+                // Optional requirements may not have any candidates.
+                if (candCaps == null)
+                {
+                    continue;
+                }
+
+                List<Requirement> outgoingReqs = new ArrayList<Requirement>(incomingReqs);
+                outgoingReqs.add(req);
+
+                for (Iterator<Capability> it = candCaps.iterator(); it.hasNext(); )
+                {
+                    Capability candCap = it.next();
+//System.out.println("+++ TRYING CAND " + candCap + " FOR " + req);
+                    try
+                    {
+                        // Try to resolve the candidate.
+                        findConsistentCandidates(
+                            candCap.getModule(),
+                            outgoingReqs,
+                            candidateMap,
+                            modulePkgMap,
+                            cycleMap);
+
+                        // If we are here, the candidate was consistent. Try to
+                        // merge the candidate into the target module's packages.
+                        mergeCandidatePackages(
+                            module,
+                            outgoingReqs,
+                            candCap,
+                            modulePkgMap,
+                            candidateMap);
+
+                        // If we are here, we merged the candidate successfully,
+                        // so we can continue with the next requirement
+                        break;
+                    }
+                    catch (ResolveException ex)
+                    {
+System.out.println("RE: " + ex);
+ex.printStackTrace();
+
+// TODO: FELIX3 RESOLVER - Is it ok to remove the failed candidate? By removing
+//       it we keep the candidateMap up to date with the selected candidate, but
+//       theoretically this eliminates some potential combinations. Are those
+//       combinations guaranteed to be failures so eliminating them is ok?
+                        it.remove();
+                        if (!it.hasNext() && !req.isOptional())
+                        {
+                            throw new ResolveException("Unresolved constraint "
+                                + req + " in " + module, module, req);
+                        }
+                    }
+                }
+            }
+        }
+
+        // If we are exiting from a cycle then decrement
+        // cycle counter, otherwise record the result.
+        if (cycleCount.intValue() > 0)
+        {
+            ((Object[]) o)[0] = new Integer(cycleCount.intValue() - 1);
+        }
+        else if (cycleCount.intValue() == 0)
+        {
+            // Record that the module was successfully populated.
+            cycleMap.put(module, Boolean.TRUE);
+        }
+    }
+
+    private void findConsistentDynamicCandidate(
+        Module module, List<Requirement> incomingReqs,
+        Map<Requirement, Set<Capability>> candidateMap,
+        Map<Module, Packages> modulePkgMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+//System.out.println("+++ RESOLVING " + module);
+        calculateExportedPackages(module, incomingReqs, modulePkgMap);
+
+        List<Requirement> reqs = new ArrayList(module.getRequirements());
+        reqs.addAll(module.getDynamicRequirements());
+        for (Requirement req : reqs)
+        {
+            // Get the candidates for the current requirement.
+            Set<Capability> candCaps = candidateMap.get(req);
+            // Optional requirements may not have any candidates.
+            if (candCaps == null)
+            {
+                continue;
+            }
+
+            List<Requirement> outgoingReqs = new ArrayList<Requirement>(incomingReqs);
+            outgoingReqs.add(req);
+
+            for (Iterator<Capability> it = candCaps.iterator(); it.hasNext(); )
+            {
+                Capability candCap = it.next();
+//System.out.println("+++ TRYING CAND " + candCap + " FOR " + req);
+                try
+                {
+                    // Try to resolve the candidate.
+                    findConsistentCandidates(
+                        candCap.getModule(),
+                        outgoingReqs,
+                        candidateMap,
+                        modulePkgMap,
+                        new HashMap());
+
+                    // If we are here, the candidate was consistent. Try to
+                    // merge the candidate into the target module's packages.
+                    mergeCandidatePackages(
+                        module,
+                        outgoingReqs,
+                        candCap,
+                        modulePkgMap,
+                        candidateMap);
+
+                    // If we are here, we merged the candidate successfully,
+                    // so we can continue with the next requirement
+                    break;
+                }
+                catch (ResolveException ex)
+                {
+System.out.println("RE: " + ex);
+ex.printStackTrace();
+// TODO: FELIX3 RESOLVER - Is it ok to remove the failed candidate? By removing
+//       it we keep the candidateMap up to date with the selected candidate, but
+//       theoretically this eliminates some potential combinations. Are those
+//       combinations guaranteed to be failures so eliminating them is ok?
+                    it.remove();
+                    if (!it.hasNext() && !req.isOptional())
+                    {
+                        throw new ResolveException("Unresolved constraint "
+                            + req + " in " + module, module, req);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void calculateExportedPackages(
+        Module module, List<Requirement> incomingReqs, Map<Module, Packages> modulePkgMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        Packages packages = new Packages();
+
+        List<Capability> caps = module.getCapabilities();
+
+        if (caps.size() > 0)
+        {
+            for (int i = 0; i < caps.size(); i++)
+            {
+// TODO: PROTO3 RESOLVER - Assume if a module imports the same package it
+//       exports that the import will overlap the export.
+                if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                    && !hasOverlappingImport(module, caps.get(i)))
+                {
+                    packages.m_exportedPkgs.put(
+                        (String) caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                        new Blame(incomingReqs, caps.get(i)));
+                }
+            }
+        }
+
+        modulePkgMap.put(module, packages);
+    }
+
+    private static boolean hasOverlappingImport(Module module, Capability cap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        List<Requirement> reqs = module.getRequirements();
+        for (int i = 0; i < reqs.size(); i++)
+        {
+            if (reqs.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                && CapabilitySet.matches(cap, reqs.get(i).getFilter()))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void mergeCandidatePackages(
+        Module current, List<Requirement> outgoingReqs,
+        Capability candCap, Map<Module, Packages> modulePkgMap,
+        Map<Requirement, Set<Capability>> candidateMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        {
+            mergeCandidatePackage(
+                current, false, new Blame(outgoingReqs, candCap), modulePkgMap, candidateMap);
+        }
+        else if (candCap.getNamespace().equals(Capability.MODULE_NAMESPACE))
+        {
+            // Get the candidate's package space to determine which packages
+            // will be visible to the current module.
+            Packages candPkgs = modulePkgMap.get(candCap.getModule());
+
+// TODO: PROTO3 RESOLVER - For now assume only exports, but eventually we also
+//       have to support re-exported packages.
+            for (Entry<String, Blame> entry : candPkgs.m_exportedPkgs.entrySet())
+            {
+                mergeCandidatePackage(
+                    current,
+                    true,
+                    new Blame(outgoingReqs, entry.getValue().m_cap),
+                    modulePkgMap,
+                    candidateMap);
+            }
+            for (Entry<String, List<Blame>> entry : candPkgs.m_requiredPkgs.entrySet())
+            {
+                List<Blame> blames = entry.getValue();
+                for (Blame blame : blames)
+                {
+// TODO: FELIX3 RESOLVER - Since a single module requirement can include many packages,
+//       it is likely we call merge too many times for the same module req. If we knew
+//       which candidates were being used to resolve this candidate's module dependencies,
+//       then we could just try to merge them directly. This info would also help in
+//       in creating wires, since we ultimately want to create wires for the selected
+//       candidates, which we are trying to deduce from the package space, but if we
+//       knew the selected candidates, we'd be done.
+                    if (blame.m_cap.getModule().equals(current))
+                    {
+                        continue;
+                    }
+
+                    Directive dir = blame.m_reqs.get(blame.m_reqs.size() - 1)
+                        .getDirective(Constants.VISIBILITY_DIRECTIVE);
+                    if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
+                    {
+                        mergeCandidatePackage(
+                            current,
+                            true,
+                            new Blame(outgoingReqs, blame.m_cap),
+                            modulePkgMap,
+                            candidateMap);
+                    }
+                }
+            }
+        }
+    }
+
+    private void mergeCandidatePackage(
+        Module current, boolean requires,
+        Blame candBlame, Map<Module, Packages> modulePkgMap,
+        Map<Requirement, Set<Capability>> candidateMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+// TODO: PROTO3 RESOLVER - Check for merging where module imports from itself,
+//       then it should be listed as an export for requiring bundles.
+        if (candBlame.m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        {
+//System.out.println("+++ MERGING " + candBlame.m_cap + " INTO " + current);
+            String pkgName = (String)
+                candBlame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue();
+
+            // Since this capability represents a package, it will become
+            // a hard constraint on the module's package space, so we need
+            // to make sure it doesn't conflict with any other hard constraints
+            // or any other uses constraints.
+
+            //
+            // First, check to see if the capability conflicts with
+            // any existing hard constraints.
+            //
+
+            Packages currentPkgs = modulePkgMap.get(current);
+            Blame currentExportedBlame = currentPkgs.m_exportedPkgs.get(pkgName);
+            Blame currentImportedBlame = currentPkgs.m_importedPkgs.get(pkgName);
+            List<Blame> currentRequiredBlames = currentPkgs.m_requiredPkgs.get(pkgName);
+
+            // We don't need to worry about an import conflicting with a required
+            // bundle's export, since imported package wires are terminal the
+            // bundle will never see the exported package from the required bundle.
+// TODO: FELIX3 - See scenario 21, this seems odd.
+            if (!requires &&
+                (currentImportedBlame != null) && !currentImportedBlame.m_cap.equals(candBlame.m_cap))
+//            if (!requires &&
+//                (((currentExportedBlame != null) && !currentExportedBlame.m_cap.equals(candBlame.m_cap))
+//                || ((currentImportedBlame != null) && !currentImportedBlame.m_cap.equals(candBlame.m_cap))))
+//                || ((currentRequiredBlames != null) && !currentRequiredBlames.contains(candBlame))))
+            {
+                // Permutate the candidate map and throw a resolve exception.
+                // NOTE: This method ALWAYS throws an exception.
+                permutateCandidates(
+                    current,
+                    pkgName,
+                    currentImportedBlame,
+                    candBlame,
+                    candidateMap);
+            }
+
+            //
+            // Second, check to see if the capability conflicts with
+            // any existing uses constraints
+            //
+
+            Packages currentPkgsCopy = currentPkgs;
+
+            if (!current.isResolved())
+            {
+                List<Blame> currentUsedBlames = currentPkgs.m_usedPkgs.get(pkgName);
+                checkExistingUsesConstraints(
+                    current, pkgName, currentUsedBlames, candBlame, modulePkgMap, candidateMap);
+
+                //
+                // Last, check to see if any uses constraints implied by the
+                // candidate conflict with any of the existing hard constraints.
+                //
+
+                // For now, create a copy of the module's package space and
+                // add the current candidate to the imported packages.
+                currentPkgsCopy = new Packages(currentPkgs);
+            }
+
+            if (requires)
+            {
+                if (currentRequiredBlames == null)
+                {
+                    currentRequiredBlames = new ArrayList<Blame>();
+                    currentPkgsCopy.m_requiredPkgs.put(pkgName, currentRequiredBlames);
+                }
+// TODO: PROTO3 RESOLVER - This is potentially modifying the original, we need to modify a copy.
+                currentRequiredBlames.add(candBlame);
+            }
+            else
+            {
+                currentPkgsCopy.m_importedPkgs.put(pkgName, candBlame);
+            }
+
+            // Verify and merge the candidate's transitive uses constraints.
+            verifyAndMergeUses(
+                current,
+                currentPkgsCopy,
+                candBlame,
+                modulePkgMap,
+                candidateMap,
+                new HashMap<String, List<Module>>());
+
+            // If we are here, then there were no conflict, so we should update
+            // the module's package space.
+            if (!current.isResolved())
+            {
+                currentPkgs.m_exportedPkgs.putAll(currentPkgsCopy.m_exportedPkgs);
+                currentPkgs.m_importedPkgs.putAll(currentPkgsCopy.m_importedPkgs);
+                currentPkgs.m_requiredPkgs.putAll(currentPkgsCopy.m_requiredPkgs);
+                currentPkgs.m_usedPkgs.putAll(currentPkgsCopy.m_usedPkgs);
+            }
+//dumpModulePkgs(current, currentPkgs);
+        }
+    }
+
+    private void checkExistingUsesConstraints(
+        Module current, String pkgName, List<Blame> currentUsedBlames,
+        Blame candBlame, Map<Module, Packages> modulePkgMap,
+        Map<Requirement, Set<Capability>> candidateMap)
+    {
+        for (int i = 0; (currentUsedBlames != null) && (i < currentUsedBlames.size()); i++)
+        {
+//System.out.println("+++ CHECK " + candBlame + " IN EXISTING " + currentUsedBlames.get(i));
+            if (!isCompatible(currentUsedBlames.get(i).m_cap, candBlame.m_cap, modulePkgMap))
+            {
+                // Permutate the candidate map and throw a resolve exception.
+                // NOTE: This method ALWAYS throws an exception.
+                permutateCandidates(
+                    current,
+                    pkgName,
+                    currentUsedBlames.get(i),
+                    candBlame,
+                    candidateMap);
+            }
+        }
+    }
+
+// TODO: PROTO3 RESOLVER - We end up with duplicates in uses constraints,
+//       see scenario 2 for an example.
+    private void verifyAndMergeUses(
+        Module current, Packages currentPkgs,
+        Blame candBlame, Map<Module, Packages> modulePkgMap,
+        Map<Requirement, Set<Capability>> candidateMap,
+        Map<String, List<Module>> cycleMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        // Check for cycles.
+        String pkgName = (String)
+            candBlame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue();
+        List<Module> list = cycleMap.get(pkgName);
+        if ((list != null) && list.contains(current))
+        {
+            return;
+        }
+        list = (list == null) ? new ArrayList<Module>() : list;
+        list.add(current);
+        cycleMap.put(pkgName, list);
+
+//System.out.println("+++ VERIFYING USES " + current + " FOR " + candBlame);
+        for (Capability candSourceCap : getPackageSources(
+            candBlame.m_cap, modulePkgMap, new ArrayList<Capability>(), new HashSet<Capability>()))
+        {
+            for (String usedPkgName : candSourceCap.getUses())
+            {
+                Blame currentExportedBlame = currentPkgs.m_exportedPkgs.get(usedPkgName);
+                Blame currentImportedBlame = currentPkgs.m_importedPkgs.get(usedPkgName);
+// TODO: PROTO3 RESOLVER - What do we do with required packages?
+                List<Blame> currentRequiredBlames = currentPkgs.m_requiredPkgs.get(usedPkgName);
+
+                Packages candSourcePkgs = modulePkgMap.get(candSourceCap.getModule());
+//System.out.println("+++ candSourceCap " + candSourceCap);
+//System.out.println("+++ candSourceCap.getModule() " + candSourceCap.getModule() + " (" + candSourceCap.getModule().isResolved() + ")");
+//System.out.println("+++ candSourcePkgs " + candSourcePkgs);
+//System.out.println("+++ candSourcePkgs.m_exportedPkgs " + candSourcePkgs.m_exportedPkgs);
+                Blame candSourceBlame = candSourcePkgs.m_exportedPkgs.get(usedPkgName);
+                candSourceBlame = (candSourceBlame != null)
+                    ? candSourceBlame
+                    : candSourcePkgs.m_importedPkgs.get(usedPkgName);
+//                sourceCap = (sourceCap != null)
+//                    ? sourceCap
+//                    : sourcePkgs.m_requiredPkgs.get(usedPkgName);
+
+                // If the candidate doesn't actually have a constraint for
+                // the used package, then just ignore it since this is likely
+                // an error in its metadata.
+                if (candSourceBlame == null)
+                {
+                    return;
+                }
+
+                // If there is no current mapping for this package, then
+                // we can just return.
+                if ((currentExportedBlame == null)
+                    && (currentImportedBlame == null)
+                    && (currentRequiredBlames == null))
+                {
+                    List<Blame> usedCaps = currentPkgs.m_usedPkgs.get(usedPkgName);
+                    if (usedCaps == null)
+                    {
+                        usedCaps = new ArrayList<Blame>();
+                        currentPkgs.m_usedPkgs.put(usedPkgName, usedCaps);
+                    }
+//System.out.println("+++ MERGING CB " + candBlame + " SB " + candSourceBlame);
+//                    usedCaps.add(new Blame(candBlame.m_reqs, sourceBlame.m_cap));
+                    usedCaps.add(candSourceBlame);
+//                    return;
+                }
+                else if (!current.isResolved())
+                {
+                    if ((currentExportedBlame != null)
+                        && !isCompatible(currentExportedBlame.m_cap, candSourceBlame.m_cap, modulePkgMap))
+                    {
+                        throw new ResolveException(
+                            "Constraint violation for package '" + usedPkgName
+                            + "' when resolving module " + current
+                            + " between existing constraint "
+                            + currentExportedBlame
+                            + " and candidate constraint "
+                            + candSourceBlame, null, null);
+                    }
+                    else if ((currentImportedBlame != null)
+                        && !isCompatible(currentImportedBlame.m_cap, candSourceBlame.m_cap, modulePkgMap))
+                    {
+//System.out.println("+++ CIB " + currentImportedBlame + " SB " + sourceBlame);
+                        // Try to remove the previously selected candidate associated
+                        // with the requirement blamed for adding the constraint. This
+                        // Permutate the candidate map.
+                        if (currentImportedBlame.m_reqs.size() != 0)
+                        {
+                            // Permutate the candidate map.
+                            for (int reqIdx = 0; reqIdx < currentImportedBlame.m_reqs.size(); reqIdx++)
+                            {
+                                Map<Requirement, Set<Capability>> copy = copyCandidateMap(candidateMap);
+                                Set<Capability> candidates =
+                                    copy.get(currentImportedBlame.m_reqs.get(reqIdx));
+                                Iterator it = candidates.iterator();
+                                it.next();
+                                it.remove();
+// TODO: PROTO3 RESOLVER - We could check before doing the candidate map copy.
+                                if (candidates.size() > 0)
+                                {
+                                    m_candidatePermutations.add(copy);
+                                }
+                            }
+                        }
+
+                        throw new ResolveException(
+                            "Constraint violation for package '" + usedPkgName
+                            + "' when resolving module " + current
+                            + " between existing constraint "
+                            + currentImportedBlame
+                            + " and candidate constraint "
+                            + candSourceBlame, null, null);
+                    }
+                }
+
+                verifyAndMergeUses(current, currentPkgs, candSourceBlame,
+                    modulePkgMap, candidateMap, cycleMap);
+            }
+        }
+    }
+
+    private void permutateCandidates(
+        Module current, String pkgName, Blame currentBlame, Blame candBlame,
+        Map<Requirement, Set<Capability>> candidateMap)
+        throws ResolveException
+    {
+        // Try to remove the previously selected candidate associated
+        // with the requirement blamed for adding the constraint. This
+        // blamed requirement may be null if the bundle itself is
+        // exports the package imposing the uses constraint.
+        if ((currentBlame.m_reqs != null) && (currentBlame.m_reqs.size() != 0))
+        {
+            // Permutate the candidate map.
+            for (int reqIdx = 0; reqIdx < currentBlame.m_reqs.size(); reqIdx++)
+            {
+                Map<Requirement, Set<Capability>> copy = copyCandidateMap(candidateMap);
+                Set<Capability> candidates = copy.get(currentBlame.m_reqs.get(reqIdx));
+                Iterator it = candidates.iterator();
+                it.next();
+                it.remove();
+                // TODO: PROTO3 RESOLVER - We could check before doing the candidate map copy.
+                if (candidates.size() > 0)
+                {
+                    m_candidatePermutations.add(copy);
+                }
+            }
+        }
+        throw new ResolveException(
+            "Constraint violation for package '"
+            + pkgName + "' when resolving module "
+            + current + " between existing constraint "
+            + currentBlame + " and candidate constraint "
+            + candBlame, null, null);
+    }
+
+    private static boolean isCompatible(
+        Capability currentCap, Capability candCap, Map<Module, Packages> modulePkgMap)
+    {
+        if ((currentCap != null) && (candCap != null))
+        {
+            List<Capability> currentSources =
+                getPackageSources(
+                    currentCap,
+                    modulePkgMap,
+                    new ArrayList<Capability>(),
+                    new HashSet<Capability>());
+            List<Capability> candSources =
+                getPackageSources(
+                    candCap,
+                    modulePkgMap,
+                    new ArrayList<Capability>(),
+                    new HashSet<Capability>());
+//System.out.println("+++ currentSources " + currentSources + " - candSources " + candSources);
+            return currentSources.containsAll(candSources) || candSources.containsAll(currentSources);
+        }
+        return true;
+    }
+
+    private static List<Capability> getPackageSources(
+        Capability cap, Map<Module, Packages> modulePkgMap, List<Capability> sources,
+        Set<Capability> cycleMap)
+    {
+        if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        {
+            if (cycleMap.contains(cap))
+            {
+                return sources;
+            }
+            cycleMap.add(cap);
+
+            Packages pkgs = modulePkgMap.get(cap.getModule());
+            sources.add(cap);
+            String pkgName = cap.getAttribute(Capability.PACKAGE_ATTR).getValue().toString();
+            List<Blame> required = pkgs.m_requiredPkgs.get(pkgName);
+            if (required != null)
+            {
+                for (Blame blame : required)
+                {
+                    getPackageSources(blame.m_cap, modulePkgMap, sources, cycleMap);
+                }
+            }
+        }
+
+        return sources;
+    }
+
+    private static Map<Requirement, Set<Capability>> copyCandidateMap(
+        Map<Requirement, Set<Capability>> candidateMap)
+    {
+        Map<Requirement, Set<Capability>> copy =
+            new HashMap<Requirement, Set<Capability>>();
+        for (Entry<Requirement, Set<Capability>> entry : candidateMap.entrySet())
+        {
+            Set<Capability> candidates = new TreeSet(new CandidateComparator());
+            candidates.addAll(entry.getValue());
+            copy.put(entry.getKey(), candidates);
+        }
+        return copy;
+    }
+
+    private static Map<Module, List<Wire>> populateWireMap(
+        Module module, Map<Module, Packages> modulePkgMap,
+        Map<Module, List<Wire>> wireMap, Map<Requirement, Set<Capability>> candidateMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        if (!module.isResolved() && !wireMap.containsKey(module))
+        {
+            wireMap.put(module, m_emptyWires);
+
+            List<Wire> packageWires = new ArrayList<Wire>();
+            List<Wire> moduleWires = new ArrayList<Wire>();
+
+            for (Requirement req : module.getRequirements())
+            {
+                Set<Capability> cands = candidateMap.get(req);
+                if ((cands != null) && (cands.size() > 0))
+                {
+                    Capability cand = cands.iterator().next();
+                    if (!cand.getModule().isResolved())
+                    {
+                        populateWireMap(cand.getModule(),
+                            modulePkgMap, wireMap, candidateMap);
+                    }
+                    // Ignore modules that import themselves.
+                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                        && !module.equals(cand.getModule()))
+                    {
+                        packageWires.add(
+                            new WireImpl(module,
+                                req,
+                                cand.getModule(),
+                                cand));
+                    }
+                    else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+                    {
+                        Packages candPkgs = modulePkgMap.get(cand.getModule());
+                        moduleWires.add(
+                            new WireModuleImpl(module,
+                                req,
+                                cand.getModule(),
+                                cand,
+                                candPkgs.getExportedAndReexportedPackages()));
+                    }
+                }
+            }
+
+            // Combine wires with module wires last.
+            packageWires.addAll(moduleWires);
+            wireMap.put(module, packageWires);
+        }
+
+        return wireMap;
+    }
+
+    private static Map<Module, List<Wire>> populateDynamicWireMap(
+        Module module, String pkgName, Map<Module, Packages> modulePkgMap,
+        Map<Module, List<Wire>> wireMap, Map<Requirement, Set<Capability>> candidateMap)
+    {
+        if (m_isInvokeCount)
+        {
+            String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+            Long count = m_invokeCounts.get(methodName);
+            count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+            m_invokeCounts.put(methodName, count);
+        }
+
+        wireMap.put(module, m_emptyWires);
+
+        List<Wire> packageWires = new ArrayList<Wire>();
+
+        Packages pkgs = modulePkgMap.get(module);
+        for (Entry<String, Blame> entry : pkgs.m_importedPkgs.entrySet())
+        {
+            if (!entry.getValue().m_cap.getModule().isResolved())
+            {
+                populateWireMap(entry.getValue().m_cap.getModule(), modulePkgMap, wireMap,
+                    candidateMap);
+            }
+
+            // Ignore modules that import themselves.
+            if (!module.equals(entry.getValue().m_cap.getModule())
+                && entry.getValue().m_cap.getAttribute(
+                    Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+            {
+                List<Attribute> attrs = new ArrayList();
+                attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+                packageWires.add(
+                    new WireImpl(
+                        module,
+                        // We need an unique requirement here or else subsequent
+                        // dynamic imports for the same dynamic requirement will
+                        // conflict with previous ones.
+                        new RequirementImpl(Capability.PACKAGE_NAMESPACE, new ArrayList(0), attrs),
+                        entry.getValue().m_cap.getModule(),
+                        entry.getValue().m_cap));
+            }
+        }
+
+        wireMap.put(module, packageWires);
+
+        return wireMap;
+    }
+
+// TODO: FELIX3 - This check should be moved to ResolverState.
+    private static void verifyNativeLibraries(Module module)
+    {
+        // Next, try to resolve any native code, since the module is
+        // not resolvable if its native code cannot be loaded.
+        List<R4Library> libs = module.getNativeLibraries();
+        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 (!module.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.size() == 0)
+            {
+                msg = "No matching native libraries found.";
+            }
+            if (msg != null)
+            {
+                throw new ResolveException(msg, module, null);
+            }
+        }
+    }
+
+    /**
+     * Checks to see if the passed in module's required execution environment
+     * is provided by the framework.
+     * @param fwkExecEvnStr The original property value of the framework's
+     *        supported execution environments.
+     * @param fwkExecEnvSet Parsed set of framework's supported execution environments.
+     * @param module The module whose required execution environment is to be to verified.
+     * @throws ResolveException if the module's required execution environment does
+     *         not match the framework's supported execution environment.
+    **/
+    private static void verifyExecutionEnvironment(
+        String fwkExecEnvStr, Set fwkExecEnvSet, Module module)
+        throws ResolveException
+    {
+        String bundleExecEnvStr = (String)
+            module.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("")
+                && (fwkExecEnvStr != null)
+                && (fwkExecEnvStr.length() > 0))
+            {
+                StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
+                boolean found = false;
+                while (tokens.hasMoreTokens() && !found)
+                {
+                    if (fwkExecEnvSet.contains(tokens.nextToken().trim()))
+                    {
+                        found = true;
+                    }
+                }
+                if (!found)
+                {
+                    throw new ResolveException(
+                        "Execution environment not supported: "
+                        + bundleExecEnvStr, module, null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Updates the framework wide execution environment string and a cached Set of
+     * execution environment tokens from the comma delimited list specified by the
+     * system variable 'org.osgi.framework.executionenvironment'.
+     * @param frameworkEnvironment Comma delimited string of provided execution environments
+    **/
+    private static Set parseExecutionEnvironments(String fwkExecEnvStr)
+    {
+        Set newSet = new HashSet();
+        if (fwkExecEnvStr != null)
+        {
+            StringTokenizer tokens = new StringTokenizer(fwkExecEnvStr, ",");
+            while (tokens.hasMoreTokens())
+            {
+                newSet.add(tokens.nextToken().trim());
+            }
+        }
+        return newSet;
+    }
+
+    private static class Packages
+    {
+        public final Map<String, Blame> m_exportedPkgs
+            = new HashMap<String, Blame>();
+        public final Map<String, Blame> m_importedPkgs
+            = new HashMap<String, Blame>();
+        public final Map<String, List<Blame>> m_requiredPkgs
+            = new HashMap<String, List<Blame>>();
+        public final Map<String, List<Blame>> m_usedPkgs
+            = new HashMap<String, List<Blame>>();
+
+        public Packages()
+        {
+        }
+
+        public Packages(Packages packages)
+        {
+            m_exportedPkgs.putAll(packages.m_exportedPkgs);
+            m_importedPkgs.putAll(packages.m_importedPkgs);
+            m_requiredPkgs.putAll(packages.m_requiredPkgs);
+            m_usedPkgs.putAll(packages.m_usedPkgs);
+        }
+
+        public List<String> getExportedAndReexportedPackages()
+        {
+            List<String> pkgs = new ArrayList();
+            for (Entry<String, Blame> entry : m_exportedPkgs.entrySet())
+            {
+                pkgs.add((String)
+                    entry.getValue().m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+            }
+            for (Entry<String, List<Blame>> entry : m_requiredPkgs.entrySet())
+            {
+                for (Blame blame : entry.getValue())
+                {
+                    Directive dir = blame.m_reqs.get(
+                        blame.m_reqs.size() - 1).getDirective(Constants.VISIBILITY_DIRECTIVE);
+                    if ((dir != null)
+                        && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
+                    {
+                        pkgs.add((String)
+                            blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+                        break;
+                    }
+                }
+            }
+            return pkgs;
+        }
+    }
+
+    private static class Blame
+    {
+        public final List<Requirement> m_reqs;
+        public final Capability m_cap;
+
+        public Blame(List<Requirement> reqs, Capability cap)
+        {
+            m_reqs = reqs;
+            m_cap = cap;
+        }
+
+        public String toString()
+        {
+            return m_cap.getModule() + "." + m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue()
+                + " BLAMED ON " + m_reqs;
+        }
+
+        public boolean equals(Object o)
+        {
+            return (o instanceof Blame) && m_reqs.equals(((Blame) o).m_reqs)
+                && m_cap.equals(((Blame) o).m_cap);
+        }
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResourceNotFoundException.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResourceNotFoundException.java
new file mode 100644
index 0000000..3cb5107
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResourceNotFoundException.java
@@ -0,0 +1,27 @@
+/* 
+ * 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;
+
+public class ResourceNotFoundException extends Exception
+{
+    public ResourceNotFoundException(String msg)
+    {
+        super(msg);
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IWire.java b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
similarity index 72%
rename from framework/src/main/java/org/apache/felix/moduleloader/IWire.java
rename to framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
index 65bd320..ba85f50 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IWire.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
@@ -1,57 +1,53 @@
-/* 
- * 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.
+/*
+ *  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.moduleloader;
+package org.apache.felix.framework.resolver;
 
+import org.apache.felix.framework.resolver.Module;
 import java.net.URL;
 import java.util.Enumeration;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
 
-/**
- * This interface represents a directed class/resource loading dependency
- * between two modules, which result when the framework resolves
- * <tt>Import-Package</tt> or <tt>Require-Bundle</tt> declarations. A wire is
- * the means by which a dependent module makes a class/resource request on
- * the providing module.
-**/
-public interface IWire
+public interface Wire
 {
     /**
      * Returns the importing module.
      * @return The importing module.
     **/
-    public IModule getImporter();
+    public Module getImporter();
     /**
      * Returns the associated requirement from the importing module that
      * resulted in the creation of this wire.
      * @return
     **/
-    public IRequirement getRequirement();
+    public Requirement getRequirement();
     /**
      * Returns the exporting module.
      * @return The exporting module.
     **/
-    public IModule getExporter();
+    public Module getExporter();
     /**
      * Returns the associated capability from the exporting module that
      * satisfies the requirement of the importing module.
      * @return
     **/
-    public ICapability getCapability();
+    public Capability getCapability();
     /**
      * Returns whether or not the wire has a given package name. For some
      * wires, such as ones for Require-Bundle, there may be many packages.
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
new file mode 100755
index 0000000..8e36f3b
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
@@ -0,0 +1,175 @@
+/*
+ *  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.net.URL;
+import java.util.Enumeration;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
+
+public class WireImpl implements Wire
+{
+    private final Module m_importer;
+    private final Requirement m_req;
+    private final Module m_exporter;
+    private final Capability m_cap;
+
+    public WireImpl(Module importer, Requirement ip, Module exporter, Capability ep)
+    {
+        m_importer = importer;
+        m_req = ip;
+        m_exporter = exporter;
+        m_cap = ep;
+    }
+
+    public Module getImporter()
+    {
+        return m_importer;
+    }
+
+    public Requirement getRequirement()
+    {
+        return m_req;
+    }
+
+    public Module getExporter()
+    {
+        return m_exporter;
+    }
+
+    public Capability getCapability()
+    {
+        return m_cap;
+    }
+
+    public String toString()
+    {
+        return m_req + " (" + m_importer + ") -> " + m_cap + " (" + m_exporter + ")";
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
+     */
+    public boolean hasPackage(String pkgName)
+    {
+        return (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
+     */
+    public Class getClass(String name) throws ClassNotFoundException
+    {
+        Class clazz = null;
+
+        // Get the package of the target class.
+        String pkgName = Util.getClassPackage(name);
+
+        // Only check when the package of the target class is
+        // the same as the package for the wire.
+        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        {
+            // Check the include/exclude filters from the target package
+            // to make sure that the class is actually visible. We delegate
+            // to the exporting module, rather than its content, so it can
+            // it can follow any internal wires it may have (e.g., if the
+            // package has multiple sources).
+// TODO: FELIX3 - Should isIncluded() be part of Capability?
+            if (((CapabilityImpl) m_cap).isIncluded(name))
+            {
+                clazz = m_exporter.getClassByDelegation(name);
+            }
+
+            // If no class was found, then we must throw an exception
+            // since the exporter for this package did not contain the
+            // requested class.
+            if (clazz == null)
+            {
+                throw new ClassNotFoundException(name);
+            }
+        }
+
+        return clazz;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
+     */
+    public URL getResource(String name) throws ResourceNotFoundException
+    {
+        URL url = null;
+
+        // Get the package of the target class.
+        String pkgName = Util.getResourcePackage(name);
+
+        // Only check when the package of the target resource is
+        // the same as the package for the wire.
+        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        {
+            // Delegate to the exporting module, rather than its
+            // content, so that it can follow any internal wires it may have
+            // (e.g., if the package has multiple sources).
+            url = m_exporter.getResourceByDelegation(name);
+
+            // If no resource was found, then we must throw an exception
+            // since the exporter for this package did not contain the
+            // requested class.
+            if (url == null)
+            {
+                throw new ResourceNotFoundException(name);
+            }
+        }
+
+        return url;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
+     */
+    public Enumeration getResources(String name) throws ResourceNotFoundException
+    {
+        Enumeration urls = null;
+
+        // Get the package of the target class.
+        String pkgName = Util.getResourcePackage(name);
+
+        // Only check when the package of the target resource is
+        // the same as the package for the wire.
+        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
+            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        {
+            urls = m_exporter.getResourcesByDelegation(name);
+
+            // If no resource was found, then we must throw an exception
+            // since the exporter for this package did not contain the
+            // requested class.
+            if (urls == null)
+            {
+                throw new ResourceNotFoundException(name);
+            }
+        }
+
+        return urls;
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
similarity index 78%
rename from framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
rename to framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
index 28671c6..42df1cd 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
@@ -16,36 +16,37 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.framework.searchpolicy;
+package org.apache.felix.framework.resolver;
 
 import java.net.URL;
-import java.util.*;
-
+import java.util.Enumeration;
+import java.util.List;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.moduleloader.*;
 
-public class R4WireModule implements IWire
+public class WireModuleImpl implements Wire
 {
-    private final IModule m_importer;
-    private final IRequirement m_requirement;
-    private final IModule m_exporter;
-    private final ICapability m_capability;
-    private final Map m_pkgMap;
+    private final Module m_importer;
+    private final Requirement m_requirement;
+    private final Module m_exporter;
+    private final Capability m_capability;
+    private final List<String> m_packages;
 
-    public R4WireModule(IModule importer, IRequirement requirement,
-        IModule exporter, ICapability capability, Map pkgMap)
+    public WireModuleImpl(Module importer, Requirement requirement,
+        Module exporter, Capability capability, List<String> packages)
     {
         m_importer = importer;
         m_requirement = requirement;
         m_exporter = exporter;
         m_capability = capability;
-        m_pkgMap = pkgMap;
+        m_packages = packages;
     }
 
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getImporter()
      */
-    public IModule getImporter()
+    public Module getImporter()
     {
         return m_importer;
     }
@@ -53,7 +54,7 @@
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getRequirement()
      */
-    public IRequirement getRequirement()
+    public Requirement getRequirement()
     {
         return m_requirement;
     }
@@ -61,7 +62,7 @@
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getExporter()
      */
-    public IModule getExporter()
+    public Module getExporter()
     {
         return m_exporter;
     }
@@ -69,7 +70,7 @@
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getCapability()
      */
-    public ICapability getCapability()
+    public Capability getCapability()
     {
         return m_capability;
     }
@@ -79,7 +80,7 @@
      */
     public boolean hasPackage(String pkgName)
     {
-        return (m_pkgMap.get(pkgName) != null);
+        return m_packages.contains(pkgName);
     }
 
     /* (non-Javadoc)
@@ -89,9 +90,7 @@
     {
         // Get the package of the target class.
         String pkgName = Util.getClassPackage(name);
-
-        ResolvedPackage rp = (ResolvedPackage) m_pkgMap.get(pkgName);
-        if (rp != null)
+        if (m_packages.contains(pkgName))
         {
             try
             {
@@ -119,9 +118,7 @@
     {
         // Get the package of the target class.
         String pkgName = Util.getResourcePackage(name);
-
-        ResolvedPackage rp = (ResolvedPackage) m_pkgMap.get(pkgName);
-        if (rp != null)
+        if (m_packages.contains(pkgName))
         {
             URL url = m_exporter.getResourceByDelegation(name);
             if (url != null)
@@ -145,10 +142,7 @@
         String pkgName = Util.getResourcePackage(name);
 
         // See if we have a resolved package for the resource's package.
-        // If so, loop through all package sources and aggregate any
-        // matching resource enumerations.
-        ResolvedPackage rp = (ResolvedPackage) m_pkgMap.get(pkgName);
-        if (rp != null)
+        if (m_packages.contains(pkgName))
         {
             Enumeration urls = m_exporter.getResourcesByDelegation(name);
             if (urls != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/CandidateSet.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/CandidateSet.java
deleted file mode 100644
index f16165c..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/CandidateSet.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import java.util.List;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
-
-class CandidateSet
-{
-    public static final int NORMAL = 0;
-    public final IModule m_module;
-    public final IRequirement m_requirement;
-    public final List m_candidates;
-    public int m_idx = 0;
-    public int m_rotated = 0;
-
-    public CandidateSet(IModule module, IRequirement requirement, List candidates)
-    {
-        super();
-        m_module = module;
-        m_requirement = requirement;
-        m_candidates = candidates;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Wire.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Wire.java
deleted file mode 100755
index 0eb232b..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4Wire.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import java.net.URL;
-import java.util.Enumeration;
-
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.Capability;
-import org.apache.felix.moduleloader.*;
-
-public class R4Wire implements IWire
-{
-    private final IModule m_importer;
-    private final IRequirement m_requirement;
-    private final IModule m_exporter;
-    private final ICapability m_capability;
-
-    public R4Wire(IModule importer, IRequirement requirement,
-        IModule exporter, ICapability capability)
-    {
-        m_importer = importer;
-        m_requirement = requirement;
-        m_exporter = exporter;
-        m_capability = capability;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getImporter()
-     */
-    public IModule getImporter()
-    {
-        return m_importer;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getRequirement()
-     */
-    public IRequirement getRequirement()
-    {
-        return m_requirement;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getExporter()
-     */
-    public IModule getExporter()
-    {
-        return m_exporter;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getCapability()
-     */
-    public ICapability getCapability()
-    {
-        return m_capability;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
-     */
-    public boolean hasPackage(String pkgName)
-    {
-        return (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-            m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName));
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
-     */
-    public Class getClass(String name) throws ClassNotFoundException
-    {
-        Class clazz = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getClassPackage(name);
-
-        // Only check when the package of the target class is
-        // the same as the package for the wire.
-        if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-            m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
-        {
-            // Check the include/exclude filters from the target package
-            // to make sure that the class is actually visible. We delegate
-            // to the exporting module, rather than its content, so it can
-            // it can follow any internal wires it may have (e.g., if the
-            // package has multiple sources).
-            if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                && ((Capability) m_capability).isIncluded(name))
-            {
-                clazz = m_exporter.getClassByDelegation(name);
-            }
-
-            // If no class was found, then we must throw an exception
-            // since the exporter for this package did not contain the
-            // requested class.
-            if (clazz == null)
-            {
-                throw new ClassNotFoundException(name);
-            }
-        }
-
-        return clazz;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
-     */
-    public URL getResource(String name) throws ResourceNotFoundException
-    {
-        URL url = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getResourcePackage(name);
-
-        // Only check when the package of the target resource is
-        // the same as the package for the wire.
-        if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-            m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
-        {
-            // Delegate to the exporting module, rather than its
-            // content, so that it can follow any internal wires it may have
-            // (e.g., if the package has multiple sources).
-            url = m_exporter.getResourceByDelegation(name);
-
-            // If no resource was found, then we must throw an exception
-            // since the exporter for this package did not contain the
-            // requested class.
-            if (url == null)
-            {
-                throw new ResourceNotFoundException(name);
-            }
-        }
-
-        return url;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
-     */
-    public Enumeration getResources(String name) throws ResourceNotFoundException
-    {
-        Enumeration urls = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getResourcePackage(name);
-
-        // Only check when the package of the target resource is
-        // the same as the package for the wire.
-        if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
-            m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
-        {
-            urls = m_exporter.getResourcesByDelegation(name);
-
-            // If no resource was found, then we must throw an exception
-            // since the exporter for this package did not contain the
-            // requested class.
-            if (urls == null)
-            {
-                throw new ResourceNotFoundException(name);
-            }
-        }
-
-        return urls;
-    }
-
-    public String toString()
-    {
-        if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-        {
-            return m_importer + " -> "
-                + m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY)
-                + " -> " + m_exporter;
-        }
-        return m_importer + " -> " + m_capability + " -> " + m_exporter;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java
deleted file mode 100755
index e3658e5..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolveException.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
-
-/**
- * <p>
- * This exception is thrown if a module cannot be resolved. The module
- * that failed to be resolved is recorded, along with the failed import target
- * identifier and version number. If the error was a result of a propagation
- * conflict, then the propagation error flag is set.
- * </p>
- * @see org.apache.felix.moduleloader.search.ImportSearchPolicy#validate(org.apache.felix.moduleloader.Module)
-**/
-public class ResolveException extends Exception
-{
-    private IModule m_module = null;
-    private IRequirement m_req = null;
-
-    /**
-     * Constructs an exception with the specified message, module,
-     * import identifier, import version number, and propagation flag.
-    **/
-    public ResolveException(String msg, IModule module, IRequirement req)
-    {
-        super(msg);
-        m_module = module;
-        m_req = req;
-    }
-
-    /**
-     * Returns the module that was being resolved.
-     * @return the module that was being resolved.
-    **/
-    public IModule getModule()
-    {
-        return m_module;
-    }
-
-    public IRequirement getRequirement()
-    {
-        return m_req;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java
deleted file mode 100644
index b75ebfa..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.felix.moduleloader.ICapability;
-
-/**
- * This utility class is a resolved package, which is comprised of a
- * set of <tt>ICapability</tt>s that is calculated by the resolver
- * algorithm. A given resolved package may have a single capability,
- * as is the case with imported packages, or it may have multiple
- * capabilities, as is the case with required bundles.
- */
-class ResolvedPackage
-{
-    public final String m_name;
-    public final CandidateSet m_cs;
-    public final List m_capList = new ArrayList();
-
-    public ResolvedPackage(String name, CandidateSet cs)
-    {
-        super();
-        m_name = name;
-        m_cs = cs;
-    }
-
-    public boolean isSubset(ResolvedPackage rp)
-    {
-        if (m_capList.size() > rp.m_capList.size())
-        {
-            return false;
-        }
-        else if (!m_name.equals(rp.m_name))
-        {
-            return false;
-        }
-        // Determine if the target set of source modules is a subset.
-        return rp.m_capList.containsAll(m_capList);
-    }
-
-    public Object clone()
-    {
-        ResolvedPackage rp = new ResolvedPackage(m_name, m_cs);
-        rp.m_capList.addAll(m_capList);
-        return rp;
-    }
-
-    public void merge(ResolvedPackage rp)
-    {
-        // Merge required packages, avoiding duplicate
-        // package sources and maintaining ordering.
-        for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
-        {
-            if (!m_capList.contains(rp.m_capList.get(capIdx)))
-            {
-                m_capList.add(rp.m_capList.get(capIdx));
-            }
-        }
-    }
-
-    public String toString()
-    {
-        return toString("", new StringBuffer()).toString();
-    }
-
-    public StringBuffer toString(String padding, StringBuffer sb)
-    {
-        sb.append(padding);
-        sb.append(m_name);
-        sb.append(" from [");
-        for (int i = 0; i < m_capList.size(); i++)
-        {
-            ICapability cap = (ICapability) m_capList.get(i);
-            sb.append(cap.getModule());
-            if ((i + 1) < m_capList.size())
-            {
-                sb.append(", ");
-            }
-        }
-        sb.append("]");
-        return sb;
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
deleted file mode 100644
index eb42f0c..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
+++ /dev/null
@@ -1,1737 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.Capability;
-import org.apache.felix.framework.util.manifestparser.R4Attribute;
-import org.apache.felix.framework.util.manifestparser.R4Directive;
-import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.util.manifestparser.Requirement;
-import org.apache.felix.moduleloader.ICapability;
-import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.IRequirement;
-import org.apache.felix.moduleloader.IWire;
-import org.osgi.framework.Constants;
-
-public class Resolver
-{
-    private final Logger m_logger;
-
-    // Execution environment.
-    private final String m_fwkExecEnvStr;
-    private final Set m_fwkExecEnvSet;
-
-    // Reusable empty array.
-    private static final IWire[] m_emptyWires = new IWire[0];
-
-    public Resolver(Logger logger, String fwkExecEnvStr)
-    {
-        m_logger = logger;
-        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
-        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
-    }
-
-    // Returns a map of resolved bundles where the key is the module
-    // and the value is an array of wires.
-    public Map resolve(ResolverState state, IModule rootModule) throws ResolveException
-    {
-        // If the module is already resolved, then we can just return.
-        if (rootModule.isResolved())
-        {
-            return null;
-        }
-
-        // This variable maps an unresolved module to a list of candidate
-        // sets, where there is one candidate set for each requirement that
-        // must be resolved. A candidate set contains the potential canidates
-        // available to resolve the requirement and the currently selected
-        // candidate index.
-        Map candidatesMap = new HashMap();
-
-        // The first step is to populate the candidates map. This
-        // will use the target module to populate the candidates map
-        // with all potential modules that need to be resolved as a
-        // result of resolving the target module. The key of the
-        // map is a potential module to be resolved and the value is
-        // a list of candidate sets, one for each of the module's
-        // requirements, where each candidate set contains the potential
-        // candidates for resolving the requirement. Not all modules in
-        // this map will be resolved, only the target module and
-        // any candidates selected to resolve its requirements and the
-        // transitive requirements this implies.
-        populateCandidatesMap(state, candidatesMap, rootModule);
-
-        // The next step is to use the candidates map to determine if
-        // the class space for the root module is consistent. This
-        // is an iterative process that transitively walks the "uses"
-        // relationships of all packages visible from the root module
-        // checking for conflicts. If a conflict is found, it "increments"
-        // the configuration of currently selected potential candidates
-        // and tests them again. If this method returns, then it has found
-        // a consistent set of candidates; otherwise, a resolve exception
-        // is thrown if it exhausts all possible combinations and could
-        // not find a consistent class space.
-        findConsistentClassSpace(state, candidatesMap, rootModule);
-
-        // The final step is to create the wires for the root module and
-        // transitively all modules that are to be resolved from the
-        // selected candidates for resolving the root module's imports.
-        // When this call returns, each module's wiring and resolved
-        // attributes are set. The resulting wiring map is used below
-        // to fire resolved events outside of the synchronized block.
-        // The resolved module wire map maps a module to its array of
-        // wires.
-        return populateWireMap(state, candidatesMap, rootModule, new HashMap());
-    }
-
-    // TODO: RESOLVER - Fix this return type.
-    // Return candidate wire in result[0] and wire map in result[1]
-    public Object[] resolveDynamicImport(ResolverState state, IModule importer, String pkgName)
-        throws ResolveException
-    {
-        ICapability candidate = null;
-        Map resolvedModuleWireMap = null;
-
-        // We can only create a dynamic import if the following
-        // conditions are met:
-        // 1. The package in question is not already imported.
-        // 2. The package in question is not accessible via require-bundle.
-        // 3. The package in question is not exported by the bundle.
-        // 4. The package in question matches a dynamic import of the bundle.
-        // The following call checks all of these conditions and returns
-        // a matching dynamic requirement if possible.
-        IRequirement dynReq = findAllowedDynamicImport(importer, pkgName);
-        if (dynReq != null)
-        {
-            // Create a new requirement based on the dynamic requirement,
-            // but substitute the precise package name for which we are
-            // looking, because it is not possible to use the potentially
-            // wildcarded version in the dynamic requirement.
-            R4Directive[] dirs = ((Requirement) dynReq).getDirectives();
-            R4Attribute[] attrs = ((Requirement) dynReq).getAttributes();
-            R4Attribute[] newAttrs = new R4Attribute[attrs.length];
-            System.arraycopy(attrs, 0, newAttrs, 0, attrs.length);
-            for (int attrIdx = 0; attrIdx < newAttrs.length; attrIdx++)
-            {
-                if (newAttrs[attrIdx].getName().equals(ICapability.PACKAGE_PROPERTY))
-                {
-                    newAttrs[attrIdx] = new R4Attribute(
-                        ICapability.PACKAGE_PROPERTY, pkgName, false);
-                    break;
-                }
-            }
-            IRequirement target = new Requirement(ICapability.PACKAGE_NAMESPACE, dirs, newAttrs);
-
-            // See if there is a candidate exporter that satisfies the
-            // constrained dynamic requirement.
-            try
-            {
-                // Get "resolved" and "unresolved" candidates and put
-                // the "resolved" candidates first.
-                List candidates = state.getResolvedCandidates(target, importer);
-                candidates.addAll(state.getUnresolvedCandidates(target, importer));
-
-                // Take the first candidate that can resolve.
-                for (int candIdx = 0;
-                    (candidate == null) && (candIdx < candidates.size());
-                    candIdx++)
-                {
-                    try
-                    {
-                        // If a map is returned, then the candidate resolved
-                        // consistently with the importer.
-                        resolvedModuleWireMap =
-                            resolveDynamicImportCandidate(
-                                state, ((ICapability) candidates.get(candIdx)).getModule(),
-                                importer);
-                        if (resolvedModuleWireMap != null)
-                        {
-                            candidate = (ICapability) candidates.get(candIdx);
-                        }
-                    }
-                    catch (ResolveException ex)
-                    {
-                        // Ignore candidates that cannot resolve.
-                    }
-                }
-
-                if (candidate != null)
-                {
-                    // Create the wire and add it to the module.
-                    Object[] result = new Object[2];
-                    result[0] = new R4Wire(
-                        importer, dynReq, candidate.getModule(),
-                        candidate);
-                    result[1] = resolvedModuleWireMap;
-                    return result;
-                }
-            }
-            catch (Exception ex)
-            {
-                m_logger.log(Logger.LOG_ERROR, "Unable to dynamically import package.", ex);
-            }
-        }
-
-        return null;
-    }
-
-    public static IRequirement findAllowedDynamicImport(IModule importer, String pkgName)
-    {
-        // We cannot import the default package, so return null in that case.
-        if (pkgName.length() == 0)
-        {
-            return null;
-        }
-
-        // If any of the module exports this package, then we cannot
-        // attempt to dynamically import it.
-        ICapability[] caps = importer.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.length); i++)
-        {
-            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                && caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
-            {
-                return null;
-            }
-        }
-        // If any of our wires have this package, then we cannot
-        // attempt to dynamically import it.
-        IWire[] wires = importer.getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
-        {
-            if (wires[i].hasPackage(pkgName))
-            {
-                return null;
-            }
-        }
-
-        // Loop through the importer's dynamic requirements to determine if
-        // there is a matching one for the package from which we want to
-        // load a class.
-        IRequirement[] dynamics = importer.getDynamicRequirements();
-        for (int dynIdx = 0;
-            (dynamics != null) && (dynIdx < dynamics.length);
-            dynIdx++)
-        {
-            // First check to see if the dynamic requirement matches the
-            // package name; this means we have to do wildcard matching.
-            String dynPkgName = ((Requirement) dynamics[dynIdx]).getTargetName();
-            boolean wildcard = (dynPkgName.lastIndexOf(".*") >= 0);
-            // Remove the "*", but keep the "." if wildcarded.
-            dynPkgName = (wildcard)
-                ? dynPkgName.substring(0, dynPkgName.length() - 1) : dynPkgName;
-            // If the dynamic requirement matches the package name, then
-            // create a new requirement for the specific package.
-            if (dynPkgName.equals("*") ||
-                pkgName.equals(dynPkgName) ||
-                (wildcard && pkgName.startsWith(dynPkgName)))
-            {
-                return dynamics[dynIdx];
-            }
-        }
-
-        return null;
-    }
-
-    private Map resolveDynamicImportCandidate(
-        ResolverState state, IModule provider, IModule importer)
-        throws ResolveException
-    {
-        // If the provider of the dynamically imported package is not
-        // resolved, then we need to calculate the candidates to resolve
-        // it and see if there is a consistent class space for the
-        // provider. If there is no consistent class space, then a resolve
-        // exception is thrown.
-        Map candidatesMap = new HashMap();
-        if (!provider.isResolved())
-        {
-            populateCandidatesMap(state, candidatesMap, provider);
-            findConsistentClassSpace(state, candidatesMap, provider);
-        }
-
-        // If the provider can be successfully resolved, then verify that
-        // its class space is consistent with the existing class space of the
-        // module that instigated the dynamic import.
-        Map moduleMap = new HashMap();
-        Map importerPkgMap = getModulePackages(moduleMap, importer, candidatesMap);
-
-        // Now we need to calculate the "uses" constraints of every package
-        // accessible to the provider module based on its current candidates.
-        Map usesMap = calculateUsesConstraints(provider, moduleMap, candidatesMap);
-
-        // Verify that none of the provider's implied "uses" constraints
-        // in the uses map conflict with anything in the importing module's
-        // package map.
-        for (Iterator iter = usesMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) iter.next();
-
-            // For the given "used" package, get that package from the
-            // importing module's package map, if present.
-            ResolvedPackage rp = (ResolvedPackage) importerPkgMap.get(entry.getKey());
-
-            // If the "used" package is also visible to the importing
-            // module, make sure there is no conflicts in the implied
-            // "uses" constraints.
-            if (rp != null)
-            {
-                // Clone the resolve package so we can modify it.
-                rp = (ResolvedPackage) rp.clone();
-
-                // Loop through all implied "uses" constraints for the current
-                // "used" package and verify that all packages are
-                // compatible with the packages of the importing module's
-                // package map.
-                List constraintList = (List) entry.getValue();
-                for (int constIdx = 0; constIdx < constraintList.size(); constIdx++)
-                {
-                    // Get a specific "uses" constraint for the current "used"
-                    // package.
-                    ResolvedPackage rpUses = (ResolvedPackage) constraintList.get(constIdx);
-                    // Determine if the implied "uses" constraint is compatible with
-                    // the improting module's packages for the given "used"
-                    // package. They are compatible if one is the subset of the other.
-                    // Retain the union of the two sets if they are compatible.
-                    if (rpUses.isSubset(rp))
-                    {
-                        // Do nothing because we already have the superset.
-                    }
-                    else if (rp.isSubset(rpUses))
-                    {
-                        // Keep the superset, i.e., the union.
-                        rp.m_capList.clear();
-                        rp.m_capList.addAll(rpUses.m_capList);
-                    }
-                    else
-                    {
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "Constraint violation for " + importer
-                            + " detected; module can see "
-                            + rp + " and " + rpUses);
-                        return null;
-                    }
-                }
-            }
-        }
-
-        return populateWireMap(state, candidatesMap, provider, new HashMap());
-    }
-
-    private void populateCandidatesMap(
-        ResolverState state, Map candidatesMap, IModule targetModule)
-        throws ResolveException
-    {
-        // Detect cycles.
-        if (candidatesMap.containsKey(targetModule))
-        {
-            return;
-        }
-
-        // Verify that any required execution environment is satisfied.
-        verifyExecutionEnvironment(m_fwkExecEnvStr, m_fwkExecEnvSet, targetModule);
-
-        // Verify that any native libraries match the current platform.
-        verifyNativeLibraries(targetModule);
-
-        // Finally, resolve any dependencies the module may have.
-
-        // Add target module to the candidates map so we can detect cycles.
-        candidatesMap.put(targetModule, null);
-
-        // Create list to hold the resolving candidate sets for the target
-        // module's requirements.
-        List candSetList = new ArrayList();
-
-        // Loop through each requirement and calculate its resolving
-        // set of candidates.
-        IRequirement[] reqs = targetModule.getRequirements();
-        for (int reqIdx = 0; (reqs != null) && (reqIdx < reqs.length); reqIdx++)
-        {
-            // Get the candidates from the "resolved" and "unresolved"
-            // package maps. The "resolved" candidates have higher priority
-            // than "unresolved" ones, so put the "resolved" candidates
-            // at the front of the list of candidates.
-            List candidates = state.getResolvedCandidates(reqs[reqIdx], targetModule);
-            candidates.addAll(state.getUnresolvedCandidates(reqs[reqIdx], targetModule));
-
-            // If we have candidates, then we need to recursively populate
-            // the resolver map with each of them.
-            ResolveException rethrow = null;
-            if (candidates.size() > 0)
-            {
-                for (Iterator it = candidates.iterator(); it.hasNext(); )
-                {
-                    ICapability candidate = (ICapability) it.next();
-
-                    try
-                    {
-                        // Only populate the resolver map with modules that
-                        // are not already resolved.
-                        if (!candidate.getModule().isResolved())
-                        {
-                            populateCandidatesMap(
-                                state, candidatesMap, candidate.getModule());
-                        }
-                    }
-                    catch (ResolveException ex)
-                    {
-                        // If we received a resolve exception, then the
-                        // current candidate is not resolvable for some
-                        // reason and should be removed from the list of
-                        // candidates. For now, just null it.
-                        it.remove();
-                        rethrow = ex;
-                    }
-                }
-            }
-
-            // If no candidates exist at this point, then throw a
-            // resolve exception unless the import is optional.
-            if ((candidates.size() == 0) && !reqs[reqIdx].isOptional())
-            {
-                // Remove invalid candidate and any cycle byproduct resolved modules.
-                removeInvalidCandidate(targetModule, candidatesMap, new ArrayList());
-
-                // If we have received an exception while trying to populate
-                // the candidates map, rethrow that exception since it might
-                // be useful. NOTE: This is not necessarily the "only"
-                // correct exception, since it is possible that multiple
-                // candidates were not resolvable, but it is better than
-                // nothing.
-                if (rethrow != null)
-                {
-                    throw rethrow;
-                }
-                else
-                {
-                    throw new ResolveException(
-                        "Unable to resolve.", targetModule, reqs[reqIdx]);
-                }
-            }
-            else if (candidates.size() > 0)
-            {
-                candSetList.add(
-                    new CandidateSet(targetModule, reqs[reqIdx], candidates));
-            }
-        }
-
-        // Now that the module's candidates have been calculated, add the
-        // candidate set list to the candidates map to be used for calculating
-        // uses constraints and ultimately wires.
-        candidatesMap.put(targetModule, candSetList);
-    }
-
-    private static void removeInvalidCandidate(
-        IModule invalidModule, Map candidatesMap, List invalidList)
-    {
-// TODO: PERFORMANCE - This could be quicker if we kept track of who depended on whom,
-//       or only those modules used as candidates or those in a cycle.
-
-        // Remove the invalid module's  candidates set list from the candidates map,
-        // since it should only contain entries for validly resolved modules.
-        candidatesMap.remove(invalidModule);
-
-        // Loop through each candidate set list in the candidates map to try
-        // to find references to the invalid module.
-        for (Iterator itCandidatesMap = candidatesMap.entrySet().iterator();
-            itCandidatesMap.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) itCandidatesMap.next();
-            IModule module = (IModule) entry.getKey();
-            List candSetList = (List) entry.getValue();
-            if (candSetList != null)
-            {
-                // Loop through each candidate set in the candidate set list
-                // to search for the invalid module.
-                for (Iterator itCandSetList = candSetList.iterator(); itCandSetList.hasNext(); )
-                {
-                    // Loop through the candidate in the candidate set and remove
-                    // the invalid module if it is found.
-                    CandidateSet cs = (CandidateSet) itCandSetList.next();
-                    for (Iterator itCandidates = cs.m_candidates.iterator();
-                        itCandidates.hasNext(); )
-                    {
-                        // If the invalid module is a candidate, then remove it from
-                        // the candidate set.
-                        ICapability candCap = (ICapability) itCandidates.next();
-                        if (candCap.getModule().equals(invalidModule))
-                        {
-                            itCandidates.remove();
-
-                            // If there are no more candidates in the candidate set, then
-                            // remove it from the candidate set list.
-                            if (cs.m_candidates.size() == 0)
-                            {
-                                itCandSetList.remove();
-
-                                // If the requirement is not optional, then add the module
-                                // to a list which will be removed after removing the current
-                                // invalid module.
-                                if (!cs.m_requirement.isOptional() && (module != invalidModule)
-                                    && !invalidList.contains(module))
-                                {
-                                    invalidList.add(module);
-                                }
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!invalidList.isEmpty())
-        {
-            while (!invalidList.isEmpty())
-            {
-                IModule m = (IModule) invalidList.remove(0);
-                removeInvalidCandidate(m, candidatesMap, invalidList);
-            }
-        }
-    }
-
-    // This flag indicates whether candidates have been rotated due to a
-    // "uses" constraint conflict. If so, then it is not necessary to perform
-    // a permutation, since rotating the candidates selected a new permutation.
-    // This part of an attempt to perform smarter permutations.
-    private boolean m_candidatesRotated = false;
-
-    private void findConsistentClassSpace(
-        ResolverState state, Map candidatesMap, IModule rootModule)
-        throws ResolveException
-    {
-        List candidatesList = null;
-
-        // The reusable module map maps a module to a map of
-        // resolved packages that are accessible by the given
-        // module. The set of resolved packages is calculated
-        // from the current candidates of the candidates map
-        // and the module's metadata.
-        Map moduleMap = new HashMap();
-
-        // Reusable map used to test for cycles.
-        Map cycleMap = new HashMap();
-
-        // Test the current potential candidates to determine if they
-        // are consistent. Keep looping until we find a consistent
-        // set or an exception is thrown.
-        while (!isSingletonConsistent(state, rootModule, moduleMap, candidatesMap) ||
-            !isClassSpaceConsistent(rootModule, moduleMap, cycleMap, candidatesMap))
-        {
-            // The incrementCandidateConfiguration() method requires
-            // ordered access to the candidates map, so we will create
-            // a reusable list once right here.
-            if (candidatesList == null)
-            {
-                candidatesList = new ArrayList();
-                for (Iterator iter = candidatesMap.entrySet().iterator();
-                    iter.hasNext(); )
-                {
-                    Map.Entry entry = (Map.Entry) iter.next();
-                    candidatesList.add(entry.getValue());
-                }
-
-                // Sort the bundles candidate sets according to a weighting
-                // based on how many multi-candidate requirements each has.
-                // The idea is to push bundles with more potential candidate
-                // permutations to the front so we can permutate over them
-                // more quickly, since they are likely to have more issues.
-                Collections.sort(candidatesList, new Comparator() {
-                    public int compare(Object o1, Object o2)
-                    {
-                        int w1 = calculateWeight((List) o1);
-                        int w2 = calculateWeight((List) o2);
-                        if (w1 < w2)
-                        {
-                            return -1;
-                        }
-                        else if (w1 > w2)
-                        {
-                            return 1;
-                        }
-                        return 0;
-                    }
-
-                    private int calculateWeight(List candSetList)
-                    {
-                        int weight = 0;
-                        for (int csIdx = 0; csIdx < candSetList.size(); csIdx++)
-                        {
-                            CandidateSet cs = (CandidateSet) candSetList.get(csIdx);
-                            if ((cs.m_candidates != null) && (cs.m_candidates.size() > 1))
-                            {
-                                weight += cs.m_candidates.size();
-                            }
-                        }
-                        return -weight;
-                    }
-                });
-            }
-
-            // Increment the candidate configuration to a new permutation so
-            // we can test again, unless some candidates have been rotated.
-            // In that case, we re-test the current permutation, since rotating
-            // the candidates effectively selects a new permutation.
-            if (!m_candidatesRotated)
-            {
-                incrementCandidateConfiguration(candidatesList);
-            }
-            else
-            {
-                m_candidatesRotated = false;
-            }
-
-            // Clear the module map.
-            moduleMap.clear();
-
-            // Clear the cycle map.
-            cycleMap.clear();
-        }
-    }
-
-    /**
-     * This methd checks to see if the target module and any of the candidate
-     * modules to resolve its dependencies violate any singleton constraints.
-     * Actually, it just creates a map of resolved singleton modules and then
-     * delegates all checking to another recursive method.
-     *
-     * @param targetModule the module that is the root of the tree of modules to check.
-     * @param moduleMap a map to cache the package space of each module.
-     * @param candidatesMap a map containing the all candidates to resolve all
-     *        dependencies for all modules.
-     * @return <tt>true</tt> if all candidates are consistent with respect to singletons,
-     *         <tt>false</tt> otherwise.
-    **/
-    private boolean isSingletonConsistent(
-        ResolverState state, IModule targetModule, Map moduleMap, Map candidatesMap)
-    {
-        // Create a map of all resolved singleton modules.
-        Map singletonMap = new HashMap();
-        IModule[] modules = state.getModules();
-        for (int i = 0; (modules != null) && (i < modules.length); i++)
-        {
-            if (modules[i].isResolved() && isSingleton(modules[i]))
-            {
-                String symName = modules[i].getSymbolicName();
-                singletonMap.put(symName, symName);
-            }
-        }
-
-        return areCandidatesSingletonConsistent(
-            state, targetModule, singletonMap, moduleMap, new HashMap(), candidatesMap);
-    }
-
-    /**
-     * This method recursive checks the target module and all of its transitive
-     * dependency modules to verify that they do not violate a singleton constraint.
-     * If the target module is a singleton, then it checks that againts existing
-     * singletons. Then it checks all current unresolved candidates recursively.
-     *
-     * @param targetModule the module that is the root of the tree of modules to check.
-     * @param singletonMap the current map of singleton symbolic names.
-     * @param moduleMap a map to cache the package space of each module.
-     * @param cycleMap a map to detect cycles.
-     * @param candidatesMap a map containing the all candidates to resolve all
-     *        dependencies for all modules.
-     * @return <tt>true</tt> if all candidates are consistent with respect to singletons,
-     *         <tt>false</tt> otherwise.
-    **/
-    private boolean areCandidatesSingletonConsistent(
-        ResolverState state, IModule targetModule,
-        Map singletonMap, Map moduleMap, Map cycleMap, Map candidatesMap)
-    {
-        // If we are in a cycle, then assume true for now.
-        if (cycleMap.get(targetModule) != null)
-        {
-            return true;
-        }
-
-        // Record the target module in the cycle map.
-        cycleMap.put(targetModule, targetModule);
-
-        // Check to see if the targetModule violates a singleton.
-        // If not and it is a singleton, then add it to the singleton
-        // map since it will constrain other singletons.
-        String symName = targetModule.getSymbolicName();
-        boolean isSingleton = isSingleton(targetModule);
-        if (isSingleton && singletonMap.containsKey(symName))
-        {
-            return false;
-        }
-        else if (isSingleton)
-        {
-            singletonMap.put(symName, symName);
-        }
-
-        // Get the package space of the target module.
-        Map pkgMap = null;
-        try
-        {
-            pkgMap = getModulePackages(moduleMap, targetModule, candidatesMap);
-        }
-        catch (ResolveException ex)
-        {
-            m_logger.log(
-                Logger.LOG_DEBUG,
-                "Constraint violation for " + targetModule + " detected.",
-                ex);
-            return false;
-        }
-
-        // Loop through all of the target module's accessible packages and
-        // verify that all packages are consistent.
-        for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) iter.next();
-            // Get the resolved package, which contains the set of all
-            // packages for the given package.
-            ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            // Loop through each capability and test if it is consistent.
-            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
-            {
-                // If the module for this capability is not resolved, then
-                // we have to see if resolving it would violate a singleton
-                // constraint.
-                ICapability cap = (ICapability) rp.m_capList.get(capIdx);
-                if (!cap.getModule().isResolved())
-                {
-                    return areCandidatesSingletonConsistent(
-                        state, cap.getModule(), singletonMap, moduleMap, cycleMap, candidatesMap);
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if the specified module is a singleton
-     * (i.e., directive singleton:=true in Bundle-SymbolicName).
-     *
-     * @param module the module to check for singleton status.
-     * @return true if the module is a singleton, false otherwise.
-    **/
-    private static boolean isSingleton(IModule module)
-    {
-        final ICapability[] modCaps = Util.getCapabilityByNamespace(
-                module, Capability.MODULE_NAMESPACE);
-        if (modCaps == null || modCaps.length == 0)
-        {
-            // this should never happen?
-            return false;
-        }
-        final R4Directive[] dirs = ((Capability) modCaps[0]).getDirectives();
-        for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.length); dirIdx++)
-        {
-            if (dirs[dirIdx].getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
-                && Boolean.valueOf(dirs[dirIdx].getValue()).booleanValue())
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isClassSpaceConsistent(
-        IModule targetModule, Map moduleMap, Map cycleMap, Map candidatesMap)
-    {
-//System.out.println("isClassSpaceConsistent("+targetModule+")");
-        // If we are in a cycle, then assume true for now.
-        if (cycleMap.get(targetModule) != null)
-        {
-            return true;
-        }
-
-        // Record the target module in the cycle map.
-        cycleMap.put(targetModule, targetModule);
-
-        // Get the package map for the target module, which is a
-        // map of all packages accessible to the module and their
-        // associated capabilities.
-        Map pkgMap = null;
-        try
-        {
-            pkgMap = getModulePackages(moduleMap, targetModule, candidatesMap);
-        }
-        catch (ResolveException ex)
-        {
-            m_logger.log(
-                Logger.LOG_DEBUG,
-                "Constraint violation for " + targetModule + " detected.",
-                ex);
-            return false;
-        }
-
-        // Loop through all of the target module's accessible packages and
-        // verify that all packages are consistent.
-        for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) iter.next();
-            // Get the resolved package, which contains the set of all
-            // capabilities for the given package.
-            ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            // Loop through each capability and test if it is consistent.
-            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
-            {
-                ICapability cap = (ICapability) rp.m_capList.get(capIdx);
-                if (!isClassSpaceConsistent(cap.getModule(), moduleMap, cycleMap, candidatesMap))
-                {
-                    return false;
-                }
-            }
-        }
-
-        // Now we need to calculate the "uses" constraints of every package
-        // accessible to the target module based on the current candidates.
-        Map usesMap = null;
-        try
-        {
-            usesMap = calculateUsesConstraints(targetModule, moduleMap, candidatesMap);
-        }
-        catch (ResolveException ex)
-        {
-            m_logger.log(
-                Logger.LOG_DEBUG,
-                "Constraint violation for " + targetModule + " detected.",
-                ex);
-            return false;
-        }
-
-        // Verify that none of the implied "uses" constraints in the uses map
-        // conflict with anything in the target module's package map.
-        for (Iterator iter = usesMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) iter.next();
-
-            // For the given "used" package, get that package from the
-            // target module's package map, if present.
-            ResolvedPackage rp = (ResolvedPackage) pkgMap.get(entry.getKey());
-
-            // If the "used" package is also visible to the target module,
-            // make sure there is no conflicts in the implied "uses"
-            // constraints.
-            if (rp != null)
-            {
-                // Clone the resolve package so we can modify it.
-                rp = (ResolvedPackage) rp.clone();
-
-                // Loop through all implied "uses" constraints for the current
-                // "used" package and verify that all packages are
-                // compatible with the packages of the root module's
-                // package map.
-                List constraintList = (List) entry.getValue();
-                for (int constIdx = 0; constIdx < constraintList.size(); constIdx++)
-                {
-                    // Get a specific "uses" constraint for the current "used"
-                    // package.
-                    ResolvedPackage rpUses = (ResolvedPackage) constraintList.get(constIdx);
-                    // Determine if the implied "uses" constraint is compatible with
-                    // the target module's packages for the given "used"
-                    // package. They are compatible if one is the subset of the other.
-                    // Retain the union of the two sets if they are compatible.
-                    if (rpUses.isSubset(rp))
-                    {
-                        // Do nothing because we already have the superset.
-                    }
-                    else if (rp.isSubset(rpUses))
-                    {
-                        // Keep the superset, i.e., the union.
-                        rp.m_capList.clear();
-                        rp.m_capList.addAll(rpUses.m_capList);
-                    }
-                    else
-                    {
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "Constraint violation for " + targetModule
-                            + " detected; module can see "
-                            + rp + " and " + rpUses);
-
-                        // If the resolved package has a candidate set, then
-                        // attempt to directly rotate the candidates to fix the
-                        // "uses" constraint conflict. The idea is rather than
-                        // blinding incrementing to the next permutation, we will
-                        // try to target the permutation to the bundle with a
-                        // conflict, which in some cases will be smarter. Only
-                        // rotate the candidates if we have more than one and we
-                        // haven't already rotated them completely.
-                        if ((rp.m_cs != null) && (rp.m_cs.m_candidates.size() > 1)
-                            && (rp.m_cs.m_rotated < rp.m_cs.m_candidates.size()))
-                        {
-                            // Rotate candidates.
-                            ICapability first = (ICapability) rp.m_cs.m_candidates.get(0);
-                            for (int i = 1; i < rp.m_cs.m_candidates.size(); i++)
-                            {
-                                rp.m_cs.m_candidates.set(i - 1, rp.m_cs.m_candidates.get(i));
-                            }
-                            rp.m_cs.m_candidates.set(rp.m_cs.m_candidates.size() - 1, first);
-                            rp.m_cs.m_rotated++;
-                            m_candidatesRotated = true;
-                        }
-
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    private static Map calculateUsesConstraints(
-        IModule targetModule, Map moduleMap, Map candidatesMap)
-        throws ResolveException
-    {
-//System.out.println("calculateUsesConstraints("+targetModule+")");
-        // Map to store calculated uses constraints. This maps a
-        // package name to a list of resolved packages, where each
-        // resolved package represents a constraint on anyone
-        // importing the given package name. This map is returned
-        // by this method.
-        Map usesMap = new HashMap();
-
-        // Re-usable map to detect cycles.
-        Map cycleMap = new HashMap();
-
-        // Get all packages accessible by the target module.
-        Map pkgMap = getModulePackages(moduleMap, targetModule, candidatesMap);
-
-        // Each package accessible from the target module is potentially
-        // comprised of one or more capabilities. The "uses" constraints
-        // implied by all capabilities must be calculated and combined to
-        // determine the complete set of implied "uses" constraints for
-        // each package accessible by the target module.
-        for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) iter.next();
-            ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
-            {
-                usesMap = calculateUsesConstraints(
-                    (ICapability) rp.m_capList.get(capIdx),
-                    moduleMap, usesMap, cycleMap, candidatesMap);
-            }
-        }
-        return usesMap;
-    }
-
-    private static Map calculateUsesConstraints(
-        ICapability capTarget, Map moduleMap, Map usesMap,
-        Map cycleMap, Map candidatesMap)
-        throws ResolveException
-    {
-//System.out.println("calculateUsesConstraints2("+psTarget.m_module+")");
-        // If we are in a cycle, then return for now.
-        if (cycleMap.get(capTarget) != null)
-        {
-            return usesMap;
-        }
-
-        // Record the target capability in the cycle map.
-        cycleMap.put(capTarget, capTarget);
-
-        // Get all packages accessible from the module of the
-        // target capability.
-        Map pkgMap = getModulePackages(moduleMap, capTarget.getModule(), candidatesMap);
-
-        // Cast to implementation class to get access to cached data.
-        Capability cap = (Capability) capTarget;
-
-        // Loop through all "used" packages of the capability.
-        for (int i = 0; i < cap.getUses().length; i++)
-        {
-            // The target capability's module should have a resolved package
-            // for the "used" package in its set of accessible packages,
-            // since it claims to use it, so get the associated resolved
-            // package.
-            ResolvedPackage rp = (ResolvedPackage) pkgMap.get(cap.getUses()[i]);
-
-            // In general, the resolved package should not be null,
-            // but check for safety.
-            if (rp != null)
-            {
-                // First, iterate through all capabilities for the resolved
-                // package associated with the current "used" package and calculate
-                // and combine the "uses" constraints for each package.
-                for (int srcIdx = 0; srcIdx < rp.m_capList.size(); srcIdx++)
-                {
-                    usesMap = calculateUsesConstraints(
-                        (ICapability) rp.m_capList.get(srcIdx),
-                        moduleMap, usesMap, cycleMap, candidatesMap);
-                }
-
-                // Then, add the resolved package for the current "used" package
-                // as a "uses" constraint too; add it to an existing constraint
-                // list if the current "used" package is already in the uses map.
-                List constraintList = (List) usesMap.get(cap.getUses()[i]);
-                if (constraintList == null)
-                {
-                    constraintList = new ArrayList();
-                }
-                constraintList.add(rp);
-                usesMap.put(cap.getUses()[i], constraintList);
-            }
-        }
-
-        return usesMap;
-    }
-
-    private static Map getModulePackages(Map moduleMap, IModule module, Map candidatesMap)
-        throws ResolveException
-    {
-        Map map = (Map) moduleMap.get(module);
-
-        if (map == null)
-        {
-            map = calculateModulePackages(module, candidatesMap);
-            moduleMap.put(module, map);
-        }
-        return map;
-    }
-
-    /**
-     * <p>
-     * Calculates the module's set of accessible packages and their
-     * assocaited package capabilities. This method uses the current candidates
-     * for resolving the module's requirements from the candidate map
-     * to calculate the module's accessible packages.
-     * </p>
-     * @param module the module whose package map is to be calculated.
-     * @param candidatesMap the map of potential candidates for resolving
-     *        the module's requirements.
-     * @return a map of the packages accessible to the specified module where
-     *         the key of the map is the package name and the value of the map
-     *         is a ResolvedPackage.
-    **/
-    private static Map calculateModulePackages(IModule module, Map candidatesMap)
-        throws ResolveException
-    {
-//System.out.println("calculateModulePackages("+module+")");
-        Map importedPackages = calculateImportedPackages(module, candidatesMap);
-        Map exportedPackages = calculateExportedPackages(module);
-        Map requiredPackages = calculateRequiredPackages(module, candidatesMap);
-
-        // Merge exported packages into required packages. If a package is both
-        // exported and required, then append the exported package to the end of
-        // the require packages; otherwise just add it to the package map.
-        for (Iterator i = exportedPackages.entrySet().iterator(); i.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) i.next();
-            ResolvedPackage rpReq = (ResolvedPackage) requiredPackages.get(entry.getKey());
-            if (rpReq != null)
-            {
-                // Merge exported and required packages, avoiding duplicate
-                // packages and maintaining ordering.
-                ResolvedPackage rpExport = (ResolvedPackage) entry.getValue();
-                rpReq.merge(rpExport);
-            }
-            else
-            {
-                requiredPackages.put(entry.getKey(), entry.getValue());
-            }
-        }
-
-        // Merge imported packages into required packages. Imports overwrite
-        // any required and/or exported package.
-        for (Iterator i = importedPackages.entrySet().iterator(); i.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) i.next();
-            requiredPackages.put(entry.getKey(), entry.getValue());
-        }
-
-        return requiredPackages;
-    }
-
-    private static Map calculateImportedPackages(IModule targetModule, Map candidatesMap)
-        throws ResolveException
-    {
-        return (candidatesMap.get(targetModule) == null)
-            ? calculateImportedPackagesResolved(targetModule)
-            : calculateImportedPackagesUnresolved(targetModule, candidatesMap);
-    }
-
-    private static Map calculateImportedPackagesUnresolved(IModule targetModule, Map candidatesMap)
-        throws ResolveException
-    {
-//System.out.println("calculateImportedPackagesUnresolved("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        // Get the candidate set list to get all candidates for
-        // all of the target module's requirements.
-        List candSetList = (List) candidatesMap.get(targetModule);
-
-        // Loop through all candidate sets that represent import dependencies
-        // for the target module and add the current candidate's packages
-        // to the imported package map.
-        for (int candSetIdx = 0;
-            (candSetList != null) && (candSetIdx < candSetList.size());
-            candSetIdx++)
-        {
-            CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
-
-            if (candCap.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                String pkgName = (String)
-                    candCap.getProperties().get(ICapability.PACKAGE_PROPERTY);
-
-                ResolvedPackage rp = new ResolvedPackage(pkgName, cs);
-                rp.m_capList.add(candCap);
-                pkgMap.put(rp.m_name, rp);
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateImportedPackagesResolved(IModule targetModule)
-        throws ResolveException
-    {
-//System.out.println("calculateImportedPackagesResolved("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        // Loop through the target module's wires for package
-        // dependencies and add the resolved packages to the
-        // imported package map.
-        IWire[] wires = targetModule.getWires();
-        for (int wireIdx = 0; (wires != null) && (wireIdx < wires.length); wireIdx++)
-        {
-            if (wires[wireIdx].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                String pkgName = (String)
-                    wires[wireIdx].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY);
-                ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
-                rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_capList.add(wires[wireIdx].getCapability());
-                pkgMap.put(rp.m_name, rp);
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateExportedPackages(IModule targetModule)
-    {
-//System.out.println("calculateExportedPackages("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        // Loop through the target module's capabilities that represent
-        // exported packages and add them to the exported package map.
-        ICapability[] caps = targetModule.getCapabilities();
-        for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
-        {
-            if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                String pkgName = (String)
-                    caps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
-                rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_capList.add(caps[capIdx]);
-                pkgMap.put(rp.m_name, rp);
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateRequiredPackages(IModule targetModule, Map candidatesMap)
-    {
-        return (candidatesMap.get(targetModule) == null)
-            ? calculateRequiredPackagesResolved(targetModule)
-            : calculateRequiredPackagesUnresolved(targetModule, candidatesMap);
-    }
-
-    private static Map calculateRequiredPackagesUnresolved(IModule targetModule, Map candidatesMap)
-    {
-//System.out.println("calculateRequiredPackagesUnresolved("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        // Loop through target module's candidate list for candidates
-        // for its module dependencies and merge re-exported packages.
-        List candSetList = (List) candidatesMap.get(targetModule);
-        for (int candSetIdx = 0;
-            (candSetList != null) && (candSetIdx < candSetList.size());
-            candSetIdx++)
-        {
-            CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
-
-            // If the capabaility is a module dependency, then flatten it to packages.
-            if (candCap.getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                // Calculate transitively required packages.
-                Map cycleMap = new HashMap();
-                cycleMap.put(targetModule, targetModule);
-                Map requireMap =
-                    calculateExportedAndReexportedPackages(
-                        candCap, candidatesMap, cycleMap);
-
-                // Take the flattened required package map for the current
-                // module dependency and merge it into the existing map
-                // of required packages.
-                for (Iterator reqIter = requireMap.entrySet().iterator(); reqIter.hasNext(); )
-                {
-                    Map.Entry entry = (Map.Entry) reqIter.next();
-                    ResolvedPackage rp = (ResolvedPackage) pkgMap.get(entry.getKey());
-                    if (rp != null)
-                    {
-                        // Merge required packages, avoiding duplicate
-                        // packages and maintaining ordering.
-                        ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
-                        rp.merge(rpReq);
-                    }
-                    else
-                    {
-                        pkgMap.put(entry.getKey(), entry.getValue());
-                    }
-                }
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateRequiredPackagesResolved(IModule targetModule)
-    {
-//System.out.println("calculateRequiredPackagesResolved("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        // Loop through target module's wires for module dependencies
-        // and merge re-exported packages.
-        IWire[] wires = targetModule.getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
-        {
-            // If the wire is a module dependency, then flatten it to packages.
-            if (wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                // Calculate transitively required packages.
-                // We can call calculateExportedAndReexportedPackagesResolved()
-                // directly, since we know all dependencies have to be resolved
-                // because this module itself is resolved.
-                Map cycleMap = new HashMap();
-                cycleMap.put(targetModule, targetModule);
-                Map requireMap =
-                    calculateExportedAndReexportedPackagesResolved(
-                        wires[i].getExporter(), cycleMap);
-
-                // Take the flattened required package map for the current
-                // module dependency and merge it into the existing map
-                // of required packages.
-                for (Iterator reqIter = requireMap.entrySet().iterator(); reqIter.hasNext(); )
-                {
-                    Map.Entry entry = (Map.Entry) reqIter.next();
-                    ResolvedPackage rp = (ResolvedPackage) pkgMap.get(entry.getKey());
-                    if (rp != null)
-                    {
-                        // Merge required packages, avoiding duplicate
-                        // packages and maintaining ordering.
-                        ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
-                        rp.merge(rpReq);
-                    }
-                    else
-                    {
-                        pkgMap.put(entry.getKey(), entry.getValue());
-                    }
-                }
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateExportedAndReexportedPackages(
-        ICapability capTarget, Map candidatesMap, Map cycleMap)
-    {
-        return (candidatesMap.get(capTarget.getModule()) == null)
-            ? calculateExportedAndReexportedPackagesResolved(capTarget.getModule(), cycleMap)
-            : calculateExportedAndReexportedPackagesUnresolved(capTarget, candidatesMap, cycleMap);
-    }
-
-    private static Map calculateExportedAndReexportedPackagesUnresolved(
-        ICapability capTarget, Map candidatesMap, Map cycleMap)
-    {
-//System.out.println("calculateExportedAndReexportedPackagesUnresolved("+psTarget.m_module+")");
-        Map pkgMap = new HashMap();
-
-        if (cycleMap.get(capTarget.getModule()) != null)
-        {
-            return pkgMap;
-        }
-
-        cycleMap.put(capTarget.getModule(), capTarget.getModule());
-
-        // Loop through all current candidates for target module's dependencies
-        // and calculate the module's complete set of required packages (and
-        // their associated packages) and the complete set of required
-        // packages to be re-exported.
-        Map allRequiredMap = new HashMap();
-        Map reexportedPkgMap = new HashMap();
-        List candSetList = (List) candidatesMap.get(capTarget.getModule());
-        for (int candSetIdx = 0; candSetIdx < candSetList.size(); candSetIdx++)
-        {
-            CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
-
-            // If the candidate is resolving a module dependency, then
-            // flatten the required packages if they are re-exported.
-            if (candCap.getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                // Determine if required packages are re-exported.
-                boolean reexport = false;
-                R4Directive[] dirs =  ((Requirement) cs.m_requirement).getDirectives();
-                for (int dirIdx = 0;
-                    !reexport && (dirs != null) && (dirIdx < dirs.length); dirIdx++)
-                {
-                    if (dirs[dirIdx].getName().equals(Constants.VISIBILITY_DIRECTIVE)
-                        && dirs[dirIdx].getValue().equals(Constants.VISIBILITY_REEXPORT))
-                    {
-                        reexport = true;
-                    }
-                }
-
-                // Recursively calculate the required packages for the
-                // current candidate.
-                Map requiredMap =
-                    calculateExportedAndReexportedPackages(candCap, candidatesMap, cycleMap);
-
-                // Merge the candidate's exported and required packages
-                // into the complete set of required packages.
-                for (Iterator reqIter = requiredMap.entrySet().iterator(); reqIter.hasNext(); )
-                {
-                    Map.Entry entry = (Map.Entry) reqIter.next();
-                    String pkgName = (String) entry.getKey();
-
-                    // Merge the current set of required packages into
-                    // the overall complete set of required packages.
-                    // We calculate all the required packages, because
-                    // despite the fact that some packages will be required
-                    // "privately" and some will be required "reexport", any
-                    // re-exported packages will ultimately need to
-                    // be combined with privately required packages,
-                    // if the required packages overlap. This is one of the
-                    // bad things about require-bundle behavior, it does not
-                    // necessarily obey the visibility rules declared in the
-                    // dependency.
-                    ResolvedPackage rp = (ResolvedPackage) allRequiredMap.get(pkgName);
-                    if (rp != null)
-                    {
-                        // Create the union of all packages.
-                        ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
-                        rp.merge(rpReq);
-                    }
-                    else
-                    {
-                        // Add package to required map.
-                        allRequiredMap.put(pkgName, entry.getValue());
-                    }
-
-                    // Keep track of all required packages to be re-exported.
-                    // All re-exported packages will need to be merged into the
-                    // target module's package map and become part of its overall
-                    // export signature.
-                    if (reexport)
-                    {
-                        reexportedPkgMap.put(pkgName, pkgName);
-                    }
-                }
-            }
-        }
-
-        // For the target module we have now calculated its entire set
-        // of required packages and their associated packages in
-        // allRequiredMap and have calculated all packages to be re-exported
-        // in reexportedPkgMap. Add all re-exported required packages to the
-        // target module's package map since they will be part of its export
-        // signature.
-        for (Iterator iter = reexportedPkgMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            String pkgName = (String) ((Map.Entry) iter.next()).getKey();
-            pkgMap.put(pkgName, allRequiredMap.get(pkgName));
-        }
-
-        // Now loop through the target module's export package capabilities and add
-        // the target module's export capability as a source for any exported packages.
-        ICapability[] candCaps = capTarget.getModule().getCapabilities();
-        for (int capIdx = 0; (candCaps != null) && (capIdx < candCaps.length); capIdx++)
-        {
-            if (candCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                String pkgName = (String)
-                    candCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
-                rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_capList.add(candCaps[capIdx]);
-                pkgMap.put(rp.m_name, rp);
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateExportedAndReexportedPackagesResolved(
-        IModule targetModule, Map cycleMap)
-    {
-//System.out.println("calculateExportedAndRequiredPackagesResolved("+targetModule+")");
-        Map pkgMap = new HashMap();
-
-        if (cycleMap.get(targetModule) != null)
-        {
-            return pkgMap;
-        }
-
-        cycleMap.put(targetModule, targetModule);
-
-        // Loop through all wires for the target module's module dependencies
-        // and calculate the module's complete set of required packages (and
-        // their associated sources) and the complete set of required
-        // packages to be re-exported.
-        Map allRequiredMap = new HashMap();
-        Map reexportedPkgMap = new HashMap();
-        IWire[] wires = targetModule.getWires();
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
-        {
-            // If the wire is a module dependency, then flatten it to packages.
-            if (wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                // Determine if required packages are re-exported.
-                boolean reexport = false;
-                R4Directive[] dirs =  ((Requirement) wires[i].getRequirement()).getDirectives();
-                for (int dirIdx = 0;
-                    !reexport && (dirs != null) && (dirIdx < dirs.length); dirIdx++)
-                {
-                    if (dirs[dirIdx].getName().equals(Constants.VISIBILITY_DIRECTIVE)
-                        && dirs[dirIdx].getValue().equals(Constants.VISIBILITY_REEXPORT))
-                    {
-                        reexport = true;
-                    }
-                }
-
-                // Recursively calculate the required packages for the
-                // wire's exporting module.
-                Map requiredMap = calculateExportedAndReexportedPackagesResolved(
-                    wires[i].getExporter(), cycleMap);
-
-                // Merge the wires exported and re-exported packages
-                // into the complete set of required packages.
-                for (Iterator reqIter = requiredMap.entrySet().iterator(); reqIter.hasNext(); )
-                {
-                    Map.Entry entry = (Map.Entry) reqIter.next();
-                    String pkgName = (String) entry.getKey();
-
-                    // Merge the current set of required packages into
-                    // the overall complete set of required packages.
-                    // We calculate all the required packages, because
-                    // despite the fact that some packages will be required
-                    // "privately" and some will be required "reexport", any
-                    // re-exported packages will ultimately need to
-                    // be combined with privately required packages,
-                    // if the required packages overlap. This is one of the
-                    // bad things about require-bundle behavior, it does not
-                    // necessarily obey the visibility rules declared in the
-                    // dependency.
-                    ResolvedPackage rp = (ResolvedPackage) allRequiredMap.get(pkgName);
-                    if (rp != null)
-                    {
-                        // Create the union of all packages.
-                        ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
-                        rp.merge(rpReq);
-                    }
-                    else
-                    {
-                        // Add package to required map.
-                        allRequiredMap.put(pkgName, entry.getValue());
-                    }
-
-                    // Keep track of all required packages to be re-exported.
-                    // All re-exported packages will need to be merged into the
-                    // target module's package map and become part of its overall
-                    // export signature.
-                    if (reexport)
-                    {
-                        reexportedPkgMap.put(pkgName, pkgName);
-                    }
-                }
-            }
-        }
-
-        // For the target module we have now calculated its entire set
-        // of required packages and their associated source capabilities in
-        // allRequiredMap and have calculated all packages to be re-exported
-        // in reexportedPkgMap. Add all re-exported required packages to the
-        // target module's package map since they will be part of its export
-        // signature.
-        for (Iterator iter = reexportedPkgMap.entrySet().iterator(); iter.hasNext(); )
-        {
-            String pkgName = (String) ((Map.Entry) iter.next()).getKey();
-            pkgMap.put(pkgName, allRequiredMap.get(pkgName));
-        }
-
-        // Now loop through the target module's export package capabilities and
-        // add the target module as a source for any exported packages.
-        ICapability[] caps = targetModule.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.length); i++)
-        {
-            if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-            {
-                String pkgName = (String)
-                    caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
-                ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
-                rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_capList.add(caps[i]);
-                pkgMap.put(rp.m_name, rp);
-            }
-        }
-
-        return pkgMap;
-    }
-
-    private static Map calculateCandidateRequiredPackages(
-        IModule module, ICapability capTarget, Map candidatesMap)
-    {
-//System.out.println("calculateCandidateRequiredPackages("+module+")");
-        Map cycleMap = new HashMap();
-        cycleMap.put(module, module);
-        return calculateExportedAndReexportedPackages(capTarget, candidatesMap, cycleMap);
-    }
-
-    private static void incrementCandidateConfiguration(List resolverList)
-        throws ResolveException
-    {
-        for (int i = 0; i < resolverList.size(); i++)
-        {
-            List candSetList = (List) resolverList.get(i);
-            for (int j = 0; j < candSetList.size(); j++)
-            {
-                CandidateSet cs = (CandidateSet) candSetList.get(j);
-                // See if we can increment the candidate set, without overflowing
-                // the candidate array bounds.
-                if ((cs.m_idx + 1) < cs.m_candidates.size())
-                {
-                    cs.m_idx++;
-                    return;
-                }
-                // If the index will overflow the candidate array bounds,
-                // then set the index back to zero and try to increment
-                // the next candidate.
-                else
-                {
-                    cs.m_idx = 0;
-                }
-            }
-        }
-        throw new ResolveException(
-            "Unable to resolve due to constraint violation.", null, null);
-    }
-
-    private static Map populateWireMap(
-        ResolverState state, Map candidatesMap, IModule importer, Map wireMap)
-    {
-        // If the module is already resolved or it is part of
-        // a cycle, then just return the wire map.
-        if (importer.isResolved() || (wireMap.get(importer) != null))
-        {
-            return wireMap;
-        }
-
-        // Get the candidate set list for the importer.
-        List candSetList = (List) candidatesMap.get(importer);
-
-        List moduleWires = new ArrayList();
-        List packageWires = new ArrayList();
-
-        // Put the module in the wireMap with an empty wire array;
-        // we do this early so we can use it to detect cycles.
-        wireMap.put(importer, m_emptyWires);
-
-        // Loop through each candidate Set and create a wire
-        // for the selected candidate for the associated import.
-        for (int candSetIdx = 0; candSetIdx < candSetList.size(); candSetIdx++)
-        {
-            // Get the current candidate set.
-            CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-
-            // Create a module wire for module dependencies.
-            if (cs.m_requirement.getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                moduleWires.add(new R4WireModule(
-                    importer,
-                    cs.m_requirement,
-                    ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
-                    ((ICapability) cs.m_candidates.get(cs.m_idx)),
-                    calculateCandidateRequiredPackages(
-                        importer, (ICapability) cs.m_candidates.get(cs.m_idx), candidatesMap)));
-            }
-            // Create a package wire for package dependencies.
-            // Filter out the case where a module imports from
-            // itself, since the module should simply load from
-            // its internal class path in this case.
-            else if (importer != ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule())
-            {
-                // Add wire for imported package.
-                packageWires.add(new R4Wire(
-                    importer,
-                    cs.m_requirement,
-                    ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
-                    ((ICapability) cs.m_candidates.get(cs.m_idx))));
-            }
-
-            // Create any necessary wires for the selected candidate module.
-            wireMap = populateWireMap(
-                state, candidatesMap,
-                ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
-                wireMap);
-        }
-
-        packageWires.addAll(moduleWires);
-        wireMap.put(importer, packageWires.toArray(new IWire[packageWires.size()]));
-
-        return wireMap;
-    }
-
-    //
-    // Utility methods.
-    //
-
-    private static void verifyNativeLibraries(IModule module)
-        throws ResolveException
-    {
-        // Next, try to resolve any native code, since the module is
-        // not resolvable if its native code cannot be loaded.
-        R4Library[] libs = module.getNativeLibraries();
-        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.length); libIdx++)
-            {
-                String entryName = libs[libIdx].getEntryName();
-                if (entryName != null)
-                {
-                    if (!module.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.length == 0)
-            {
-                msg = "No matching native libraries found.";
-            }
-            if (msg != null)
-            {
-                throw new ResolveException(msg, module, null);
-            }
-        }
-    }
-
-    /**
-     * Checks to see if the passed in module's required execution environment
-     * is provided by the framework.
-     * @param fwkExecEvnStr The original property value of the framework's
-     *        supported execution environments.
-     * @param fwkExecEnvSet Parsed set of framework's supported execution environments.
-     * @param module The module whose required execution environment is to be to verified.
-     * @throws ResolveException if the module's required execution environment does
-     *         not match the framework's supported execution environment.
-    **/
-    private static void verifyExecutionEnvironment(
-        String fwkExecEnvStr, Set fwkExecEnvSet, IModule module)
-        throws ResolveException
-    {
-        String bundleExecEnvStr = (String)
-            module.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("")
-                && (fwkExecEnvStr != null)
-                && (fwkExecEnvStr.length() > 0))
-            {
-                StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
-                boolean found = false;
-                while (tokens.hasMoreTokens() && !found)
-                {
-                    if (fwkExecEnvSet.contains(tokens.nextToken().trim()))
-                    {
-                        found = true;
-                    }
-                }
-                if (!found)
-                {
-                    throw new ResolveException(
-                        "Execution environment not supported: "
-                        + bundleExecEnvStr, module, null);
-                }
-            }
-        }
-    }
-
-    /**
-     * Updates the framework wide execution environment string and a cached Set of
-     * execution environment tokens from the comma delimited list specified by the
-     * system variable 'org.osgi.framework.executionenvironment'.
-     * @param frameworkEnvironment Comma delimited string of provided execution environments
-    **/
-    private static Set parseExecutionEnvironments(String fwkExecEnvStr)
-    {
-        Set newSet = new HashSet();
-        if (fwkExecEnvStr != null)
-        {
-            StringTokenizer tokens = new StringTokenizer(fwkExecEnvStr, ",");
-            while (tokens.hasMoreTokens())
-            {
-                newSet.add(tokens.nextToken().trim());
-            }
-        }
-        return newSet;
-    }
-
-    //
-    // Inner classes.
-    //
-
-    public static interface ResolverState
-    {
-        IModule[] getModules();
-        List getResolvedCandidates(IRequirement req, IModule reqModule);
-        List getUnresolvedCandidates(IRequirement req, IModule reqModule);
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IModule.java b/framework/src/main/java/org/apache/felix/moduleloader/IModule.java
deleted file mode 100644
index 57a9018..0000000
--- a/framework/src/main/java/org/apache/felix/moduleloader/IModule.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.moduleloader;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Map;
-import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-
-public interface IModule
-{
-    final static int EAGER_ACTIVATION = 0;
-    final static int LAZY_ACTIVATION = 1;
-
-    void setSecurityContext(Object securityContext);
-    Object getSecurityContext();
-
-    // Metadata access methods.
-    Map getHeaders();
-    boolean isExtension();
-    String getSymbolicName();
-    Version getVersion();
-    ICapability[] getCapabilities();
-    IRequirement[] getRequirements();
-    IRequirement[] getDynamicRequirements();
-    R4Library[] getNativeLibraries();
-    int getDeclaredActivationPolicy();
-
-    // Run-time data access methods.
-    Bundle getBundle();
-    String getId();
-    IWire[] getWires();
-    boolean isResolved();
-
-    // Content access methods.
-    IContent getContent();
-    Class getClassByDelegation(String name) throws ClassNotFoundException;
-    URL getResourceByDelegation(String name);
-    Enumeration getResourcesByDelegation(String name);
-    URL getEntry(String name);
-
-    // TODO: ML - For expediency, the index argument was added to these methods
-    // but it is not clear that this makes sense in the long run. This needs to
-    // be readdressed in the future, perhaps by the spec to clearly indicate
-    // how resources on the bundle class path are searched, which is why we
-    // need the index number in the first place -- to differentiate among
-    // resources with the same name on the bundle class path. This was previously
-    // handled as part of the resource path, but that approach is not spec
-    // compliant.
-    boolean hasInputStream(int index, String urlPath)
-        throws IOException;
-    InputStream getInputStream(int index, String urlPath)
-        throws IOException;
-}
\ No newline at end of file
