diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 7a677ac..99f0420 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -124,25 +124,28 @@
     {
         // Remove the bundle's associated modules from the resolver state
         // and close them.
-        for (int i = 0; i < m_modules.size(); i++)
+        for (Module m : m_modules)
         {
-            getFramework().getResolverState().removeModule(m_modules.get(i));
-            ((ModuleImpl) m_modules.get(i)).close();
-        }
-    }
+            // Remove the module from the resolver state.
+            getFramework().getResolver().removeModule(m);
 
-    /**
-     * This is sort of a hacky method called after uninstalling a bundle.
-     * If the bundle is a fragment, this will unmerge it from any unresolved
-     * hosts. This is necessary since fragments are pre-merged into unresolved
-     * hosts. If uninstalled fragments are not unmerged from unresolved hosts,
-     * any attempts to subsequently resolve the host will result in an exception.
-     */
-    synchronized void cleanAfterUninstall()
-    {
-        for (int i = 0; i < m_modules.size(); i++)
-        {
-            getFramework().getResolverState().unmergeFragment(m_modules.get(i));
+            // Set fragments to null, which will remove the module from all
+            // of its dependent fragment modules.
+            try
+            {
+                ((ModuleImpl) m).attachFragments(null);
+            }
+            catch (Exception ex)
+            {
+                getFramework().getLogger().log(
+                    m.getBundle(), Logger.LOG_ERROR, "Error detaching fragments.", ex);
+            }
+            // Set wires to null, which will remove the module from all
+            // of its dependent modules.
+            ((ModuleImpl) m).setWires(null);
+
+            // Close the module's content.
+            ((ModuleImpl) m).close();
         }
     }
 
@@ -1100,7 +1103,7 @@
         {
             // Since revising a module adds the module to the global
             // state, we must remove it from the global state on rollback.
-            getFramework().getResolverState().removeModule(m);
+            getFramework().getResolver().removeModule(m);
         }
         return m_archive.rollbackRevise();
     }
@@ -1139,7 +1142,7 @@
         {
             // Now that the module is added to the bundle, we can update
             // the resolver's module state.
-            getFramework().getResolverState().addModule(module);
+            getFramework().getResolver().addModule(module);
         }
     }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index 36d673a..bb57b0c 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -36,7 +36,7 @@
 import java.util.NoSuchElementException;
 import java.util.Set;
 
-import org.apache.felix.framework.Felix.FelixResolver;
+import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.capabilityset.Attribute;
 import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.Directive;
@@ -199,7 +199,6 @@
         {
             m_capabilities = new ArrayList<Capability>(0);
             m_logger.log(
-                felix,
                 Logger.LOG_ERROR,
                 "Error parsing system bundle export statement: "
                 + syspkgs, ex);
@@ -726,7 +725,7 @@
             return null;
         }
 
-        public FelixResolver getResolver()
+        public StatefulResolver getResolver()
         {
             return null;
         }
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index bdd8a6e..542a0fa 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -24,7 +24,6 @@
 import java.security.*;
 import java.util.*;
 import java.util.Map.Entry;
-import org.apache.felix.framework.ModuleImpl.FragmentRequirement;
 import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
 import org.apache.felix.framework.cache.BundleArchive;
 import org.apache.felix.framework.cache.BundleCache;
@@ -76,6 +75,7 @@
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.startlevel.StartLevel;
+import sun.org.mozilla.javascript.internal.UintMap;
 
 public class Felix extends BundleImpl implements Framework
 {
@@ -92,9 +92,8 @@
     // Mutable configuration properties passed into constructor.
     private final Map m_configMutableMap;
 
-    // MODULE FACTORY.
-    private final FelixResolverState m_resolverState;
-    private final FelixResolver m_felixResolver;
+    // Resolver and resolver state.
+    private final StatefulResolver m_resolver;
 
     // Lock object used to determine if an individual bundle
     // lock or the global lock can be acquired.
@@ -364,10 +363,11 @@
         m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
 
         // Create a resolver and its state.
-        m_resolverState = new FelixResolverState(
-            m_logger, (String) m_configMap.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT));
-        m_felixResolver = new FelixResolver(
-            new ResolverImpl(m_logger), m_resolverState);
+        m_resolver = new StatefulResolver(
+            new ResolverImpl(m_logger),
+            new ResolverStateImpl(
+                m_logger,
+                (String) m_configMap.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT)));
 
         // Create the extension manager, which we will use as the module
         // definition for creating the system bundle module.
@@ -394,14 +394,9 @@
         return m_configMap;
     }
 
-    FelixResolver getResolver()
+    StatefulResolver getResolver()
     {
-        return m_felixResolver;
-    }
-
-    FelixResolverState getResolverState()
-    {
-        return m_resolverState;
+        return m_resolver;
     }
 
     URLStreamHandler getBundleStreamHandler()
@@ -641,7 +636,7 @@
                 // state to be set to RESOLVED.
                 try
                 {
-                    m_felixResolver.resolve(getCurrentModule());
+                    m_resolver.resolve(getCurrentModule());
                 }
                 catch (ResolveException ex)
                 {
@@ -1989,7 +1984,7 @@
                         {
                             m_extensionManager.addExtensionBundle(this, bundle);
 // TODO: REFACTOR - Perhaps we could move this into extension manager.
-                            m_resolverState.refreshSystemBundleModule(m_extensionManager.getModule());
+                            m_resolver.addModule(m_extensionManager.getModule());
 // TODO: REFACTOR - Not clear why this is here. We should look at all of these steps more closely.
                             setBundleStateAndNotify(bundle, Bundle.RESOLVED);
                         }
@@ -2374,10 +2369,6 @@
             // Set state to uninstalled.
             setBundleStateAndNotify(bundle, Bundle.UNINSTALLED);
             bundle.setLastModified(System.currentTimeMillis());
-
-            // If this bundle is a fragment, unmerge it from any
-            // unresolved hosts.
-            bundle.cleanAfterUninstall();
         }
         finally
         {
@@ -2552,7 +2543,7 @@
                 else
                 {
                     m_extensionManager.addExtensionBundle(this, bundle);
-                    m_resolverState.refreshSystemBundleModule(m_extensionManager.getModule());
+                    m_resolver.addModule(m_extensionManager.getModule());
                 }
             }
             catch (Throwable ex)
@@ -3135,7 +3126,7 @@
         List<Attribute> attrs = new ArrayList<Attribute>(1);
         attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
         Requirement req = new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<Capability> exports = m_resolverState.getCandidates(null, req, false);
+        Set<Capability> exports = m_resolver.getCandidates(null, req, false);
 
         // We only want resolved capabilities.
         for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
@@ -3282,7 +3273,7 @@
                         attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
                         Requirement req =
                             new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-                        Set<Capability> exports = m_resolverState.getCandidates(null, req, false);
+                        Set<Capability> exports = m_resolver.getCandidates(null, req, false);
                         // We only want resolved capabilities.
                         for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
                         {
@@ -3436,13 +3427,13 @@
     {
         try
         {
-            m_felixResolver.resolve(bundle.getCurrentModule());
+            m_resolver.resolve(bundle.getCurrentModule());
         }
         catch (ResolveException ex)
         {
             if (ex.getModule() != null)
             {
-                Bundle b = ((ModuleImpl) ex.getModule()).getBundle();
+                Bundle b = ex.getModule().getBundle();
                 throw new BundleException(
                     "Unresolved constraint in bundle "
                     + b + ": " + ex.getMessage());
@@ -3974,18 +3965,34 @@
     // Miscellaneous inner classes.
     //
 
-    public class FelixResolver
+    class StatefulResolver
     {
         private final Resolver m_resolver;
-        private final FelixResolverState m_resolverState;
+        private final ResolverStateImpl m_resolverState;
 
-        public FelixResolver(Resolver resolver, FelixResolverState resolverState)
+        StatefulResolver(Resolver resolver, ResolverStateImpl resolverState)
         {
             m_resolver = resolver;
             m_resolverState = resolverState;
         }
 
-        public void resolve(Module rootModule) throws ResolveException
+        void addModule(Module m)
+        {
+            m_resolverState.addModule(m);
+        }
+
+        void removeModule(Module m)
+        {
+            m_resolverState.removeModule(m);
+        }
+
+        Set<Capability> getCandidates(
+            Module reqModule, Requirement req, boolean obeyMandatory)
+        {
+            return m_resolverState.getCandidates(reqModule, req, obeyMandatory);
+        }
+
+        void resolve(Module rootModule) throws ResolveException
         {
             // Although there is a race condition to check the bundle state
             // then lock it, we do this because we don't want to acquire the
@@ -4013,48 +4020,16 @@
                         return;
                     }
 
-                    // If the root module to resolve is a fragment, then we
-                    // must find a host to attach it to and resolve the host
-                    // instead, since the underlying resolver doesn't know
-                    // how to deal with fragments.
-                    Module newRootModule = m_resolverState.findHost(rootModule);
-                    if (!Util.isFragment(newRootModule))
-                    {
-                        // Check singleton status.
-                        m_resolverState.checkSingleton(newRootModule);
+                    // Check singleton status.
+// TOOD: FRAGMENT RESOLVER - Merge singleton handling into resolver.
+//                    m_resolverState.checkSingleton(rootModule);
 
-                        boolean repeat;
-                        do
-                        {
-                            repeat = false;
-                            try
-                            {
-                                // Resolve the module.
-                                wireMap = m_resolver.resolve(m_resolverState, newRootModule);
+                    // Resolve the module.
+                    wireMap = m_resolver.resolve(
+                        m_resolverState, rootModule, m_resolverState.getFragments());
 
-                                // Mark all modules as resolved.
-                                markResolvedModules(wireMap);
-                            }
-                            catch (ResolveException ex)
-                            {
-                                if ((ex.getRequirement() != null)
-                                    && (ex.getRequirement() instanceof FragmentRequirement)
-                                    && (rootModule !=
-                                        ((FragmentRequirement) ex.getRequirement()).getFragment()))
-                                {
-                                    m_resolverState.detachFragment(
-                                        newRootModule,
-                                        ((FragmentRequirement) ex.getRequirement()).getFragment());
-                                    repeat = true;
-                                }
-                                else
-                                {
-                                    throw ex;
-                                }
-                            }
-                        }
-                        while (repeat);
-                    }
+                    // Mark all modules as resolved.
+                    markResolvedModules(wireMap);
                 }
                 finally
                 {
@@ -4066,7 +4041,7 @@
             }
         }
 
-        public Wire resolve(Module module, String pkgName) throws ResolveException
+        Wire resolve(Module module, String pkgName) throws ResolveException
         {
             Wire candidateWire = null;
             // We cannot dynamically import if the module is not already resolved
@@ -4100,7 +4075,8 @@
                         }
                     }
 
-                    wireMap = m_resolver.resolve(m_resolverState, module, pkgName);
+                    wireMap = m_resolver.resolve(
+                        m_resolverState, module, pkgName, m_resolverState.getFragments());
 
                     if ((wireMap != null) && wireMap.containsKey(module))
                     {
@@ -4135,15 +4111,9 @@
             return candidateWire;
         }
 
-        public synchronized Set<Capability> getCandidates(
-            Module reqModule, Requirement req, boolean obeyMandatory)
-        {
-            return m_resolverState.getCandidates(reqModule, req, obeyMandatory);
-        }
-
         // This method duplicates a lot of logic from:
         // ResolverImpl.getDynamicImportCandidates()
-        public boolean isAllowedDynamicImport(Module module, String pkgName)
+        boolean isAllowedDynamicImport(Module module, String pkgName)
         {
             // Unresolved modules cannot dynamically import, nor can the default
             // package be dynamically imported.
@@ -4196,42 +4166,136 @@
         }
 
         private void markResolvedModules(Map<Module, List<Wire>> wireMap)
+            throws ResolveException
         {
+// DO THIS IN THREE PASSES:
+// 1. Aggregate fragments per host.
+// 2. Attach wires and fragments to hosts.
+//    -> If fragments fail to attach, then undo.
+// 3. Mark hosts and fragments as resolved.
             if (wireMap != null)
             {
-                Iterator<Entry<Module, List<Wire>>> iter = wireMap.entrySet().iterator();
-                // Iterate over the map to mark the modules as resolved and
-                // update our resolver data structures.
-                while (iter.hasNext())
+                // First pass: Loop through the wire map to find the host wires
+                // for any fragments and map a host to all of its fragments.
+                Map<Module, List<Module>> hosts = new HashMap<Module, List<Module>>();
+                for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
                 {
-                    Entry<Module, List<Wire>> entry = iter.next();
                     Module module = entry.getKey();
                     List<Wire> wires = entry.getValue();
 
-                    // Only add wires attribute if some exist; export
-                    // only modules may not have wires.
-                    for (int wireIdx = 0; wireIdx < wires.size(); wireIdx++)
+                    if (Util.isFragment(module))
                     {
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "WIRE: " + wires.get(wireIdx));
+                        for (Iterator<Wire> itWires = wires.iterator(); itWires.hasNext(); )
+                        {
+                            Wire w = itWires.next();
+                            List<Module> fragments = hosts.get(w.getExporter());
+                            if (fragments == null)
+                            {
+                                fragments = new ArrayList<Module>();
+                                hosts.put(w.getExporter(), fragments);
+                            }
+                            fragments.add(w.getImporter());
+                        }
                     }
+                }
+
+                // Second pass: Loop through the wire map to set wires and attach
+                // fragments, if any.
+                for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
+                {
+                    Module module = entry.getKey();
+                    List<Wire> wires = entry.getValue();
+
+// TODO: FRAGMENT RESOLVER - Better way to handle log level?
+                    for (Iterator<Wire> itWires = wires.iterator(); itWires.hasNext(); )
+                    {
+                        Wire w = itWires.next();
+                        if (!Util.isFragment(module))
+                        {
+                            m_logger.log(Logger.LOG_DEBUG, "WIRE: " + w);
+                        }
+                        else
+                        {
+                            m_logger.log(
+                                Logger.LOG_DEBUG,
+                                "FRAGMENT WIRE: "
+                                + module + " -> hosted by -> " + w.getExporter());
+                        }
+                    }
+
+                    // Set the module's wires.
                     ((ModuleImpl) module).setWires(wires);
 
-                    // Resolve all attached fragments.
-                    List<Module> fragments = ((ModuleImpl) module).getFragments();
-                    for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
+                    // Attach fragments, if any.
+                    List<Module> fragments = hosts.get(module);
+                    if (fragments != null)
                     {
-                        ((ModuleImpl) fragments.get(i)).setResolved();
-                        // Update the state of the module's bundle to resolved as well.
-                        markBundleResolved(fragments.get(i));
-                        m_logger.log(((ModuleImpl) fragments.get(i)).getBundle(),
-                            Logger.LOG_DEBUG,
-                            "FRAGMENT WIRE: " + fragments.get(i) + " -> hosted by -> " + module);
+                        try
+                        {
+                            ((ModuleImpl) module).attachFragments(fragments);
+                        }
+                        catch (Exception ex)
+                        {
+                            // This is a fatal error, so undo everything and
+                            // throw an exception.
+                            for (Entry<Module, List<Wire>> reentry : wireMap.entrySet())
+                            {
+                                module = reentry.getKey();
+
+                                // Undo wires.
+                                ((ModuleImpl) module).setWires(null);
+
+                                fragments = hosts.get(module);
+                                if (fragments != null)
+                                {
+                                    try
+                                    {
+                                        // Undo fragments.
+                                        ((ModuleImpl) module).attachFragments(null);
+                                    }
+                                    catch (Exception ex2)
+                                    {
+                                        // We are in big trouble.
+                                        RuntimeException rte = new RuntimeException(
+                                            "Unable to clean up resolver failure.", ex2);
+                                        m_logger.log(
+                                            Logger.LOG_ERROR,
+                                            rte.getMessage(), ex2);
+                                        throw rte;
+                                    }
+
+                                    // Reindex host with no fragments.
+                                    m_resolverState.addModule(module);
+                                }
+                            }
+
+                            ResolveException re = new ResolveException(
+                                "Unable to attach fragments to " + module,
+                                module, null);
+                            re.initCause(ex);
+                            m_logger.log(
+                                Logger.LOG_ERROR,
+                                re.getMessage(), ex);
+                            throw re;
+                        }
+
+                        // Reindex host with attached fragments.
+                        m_resolverState.addModule(module);
                     }
-                    // Update the resolver state to show the module as resolved.
+                }
+
+                // Third pass: Loop through the wire map to mark modules as resolved
+                // and update the resolver state.
+                for (Entry<Module, List<Wire>> entry : wireMap.entrySet())
+                {
+                    Module module = entry.getKey();
+                    // Mark module as resolved.
                     ((ModuleImpl) module).setResolved();
-                    m_resolverState.moduleResolved(module);
+                    // Update resolver state to remove substituted capabilities.
+                    if (!Util.isFragment(module))
+                    {
+                        m_resolverState.removeSubstitutedCapabilities(module);
+                    }
                     // Update the state of the module's bundle to resolved as well.
                     markBundleResolved(module);
                 }
@@ -4419,7 +4483,7 @@
                 }
                 catch (Throwable throwable)
                 {
-                    m_logger.log(Felix.this,
+                    m_logger.log(
                         Logger.LOG_WARNING,
                         "Exception stopping a system bundle activator.",
                         throwable);
diff --git a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java b/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
deleted file mode 100644
index ca74100..0000000
--- a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
+++ /dev/null
@@ -1,955 +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;
-
-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.Set;
-import java.util.StringTokenizer;
-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.manifestparser.R4Library;
-import org.osgi.framework.BundlePermission;
-import org.osgi.framework.PackagePermission;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-public class FelixResolverState implements Resolver.ResolverState
-{
-    private final Logger m_logger;
-    // List of all modules.
-    private final List<Module> m_modules;
-    // Capability sets.
-    private final Map<String, CapabilitySet> m_capSets;
-    // Maps fragment symbolic names to list of fragment modules sorted by version.
-    private final Map<String, List<Module>> m_fragmentMap = new HashMap<String, List<Module>>();
-    // Maps singleton symbolic names to list of modules sorted by version.
-    private final Map<String, List<Module>> m_singletons = new HashMap<String, List<Module>>();
-    // Execution environment.
-    private final String m_fwkExecEnvStr;
-    // Parsed framework environments
-    private final Set<String> m_fwkExecEnvSet;
-
-    public FelixResolverState(Logger logger, String fwkExecEnvStr)
-    {
-        m_logger = logger;
-        m_modules = new ArrayList<Module>();
-        m_capSets = new HashMap<String, CapabilitySet>();
-
-        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
-        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
-
-        List<String> indices = new ArrayList<String>();
-        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
-        m_capSets.put(Capability.MODULE_NAMESPACE, new CapabilitySet(indices, true));
-
-        indices = new ArrayList<String>();
-        indices.add(Capability.PACKAGE_ATTR);
-        m_capSets.put(Capability.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
-
-        indices = new ArrayList<String>();
-        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
-        m_capSets.put(Capability.HOST_NAMESPACE,  new CapabilitySet(indices, true));
-    }
-
-    public synchronized void addModule(Module module)
-    {
-        if (isSingleton(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;
-            }
-        }
-
-        if ((module != null) && Util.isFragment(module))
-        {
-            addFragment(module);
-        }
-        else if (module != null)
-        {
-            addHost(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.isEmpty())
-            {
-                m_singletons.remove(module.getSymbolicName());
-            }
-        }
-
-        if (Util.isFragment(module))
-        {
-            removeFragment(module);
-        }
-        else
-        {
-            removeHost(module);
-        }
-    }
-
-    public void detachFragment(Module host, Module fragment)
-    {
-        List<Module> fragments = new ArrayList<Module>(((ModuleImpl) host).getFragments());
-        fragments.remove(fragment);
-        removeFragment(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)
-            {
-                // Ignore
-            }
-            m_logger.log(host.getBundle(), 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 (Module mod : modules)
-            {
-                if (mod.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
-                {
-                    addHost(module);
-                }
-            }
-        }
-    }
-
-    private void addFragment(Module fragment)
-    {
-// TODO: FRAGMENT - This should check to make sure that the host allows fragments.
-        indexModule(m_fragmentMap, fragment);
-
-        // Loop through all matching hosts seeing if we should attach the
-        // new fragment. We should attach the new fragment if the existing
-        // unresolved host doesn't currently have a fragment of the same
-        // symbolic name attached to it or if the currently attached fragment
-        // is a lower version.
-        Set<Capability> hostCaps = getMatchingHostCapabilities(fragment);
-        for (Capability cap : hostCaps)
-        {
-            Module host = cap.getModule();
-
-            // Get the fragments currently attached to the host so we
-            // can remove the older version of the current fragment, if any.
-            List<Module> fragments = ((ModuleImpl) host).getFragments();
-            Module attachedFragment = null;
-            for (int fragIdx = 0;
-                (fragments != null) && (attachedFragment == null) && (fragIdx < fragments.size());
-                fragIdx++)
-            {
-                if (fragments.get(fragIdx).getSymbolicName()
-                    .equals(fragment.getSymbolicName()))
-                {
-                    attachedFragment = fragments.get(fragIdx);
-                }
-            }
-
-            if ((attachedFragment == null)
-                || (attachedFragment.getVersion().compareTo(fragment.getVersion()) <= 0))
-            {
-                // Create a copy of the fragment list and remove the attached
-                // fragment, if necessary.
-                List<Module> newFragments = (fragments == null)
-                    ? new ArrayList<Module>()
-                    : new ArrayList<Module>(fragments);
-                if (attachedFragment != null)
-                {
-                    newFragments.remove(attachedFragment);
-                }
-
-                // Now add the new fragment in bundle ID order.
-                int index = -1;
-                for (int listIdx = 0;
-                    (index < 0) && (listIdx < newFragments.size());
-                    listIdx++)
-                {
-                    Module f = newFragments.get(listIdx);
-                    if (fragment.getBundle().getBundleId()
-                        < f.getBundle().getBundleId())
-                    {
-                        index = listIdx;
-                    }
-                }
-                newFragments.add(
-                    (index < 0) ? newFragments.size() : index, fragment);
-
-                // Remove host's existing exported packages from index.
-                List<Capability> caps = host.getCapabilities();
-                removeCapabilities(caps);
-
-                // Attach the new fragments to the host.
-                fragments = (newFragments.isEmpty()) ? null : newFragments;
-                try
-                {
-                    ((ModuleImpl) host).attachFragments(fragments);
-                }
-                catch (Exception ex)
-                {
-                    // Try to clean up by removing all fragments.
-                    try
-                    {
-                        ((ModuleImpl) host).attachFragments(null);
-                    }
-                    catch (Exception ex2)
-                    {
-                        // Ignore
-                    }
-                    m_logger.log(host.getBundle(), Logger.LOG_ERROR,
-                        "Serious error attaching fragments.", ex);
-                }
-
-                // Reindex the host's exported packages.
-                caps = host.getCapabilities();
-                addCapabilities(caps);
-            }
-        }
-    }
-
-    private void removeFragment(Module fragment)
-    {
-        // Get fragment list, which may be null for system bundle fragments.
-        List<Module> fragList = m_fragmentMap.get(fragment.getSymbolicName());
-        if (fragList != null)
-        {
-            // Remove from fragment map.
-            fragList.remove(fragment);
-            if (fragList.isEmpty())
-            {
-                m_fragmentMap.remove(fragment.getSymbolicName());
-            }
-
-            // If we have any matching hosts, then attempt to remove the
-            // fragment from any merged hosts still in the installed state.
-            Set<Capability> hostCaps = getMatchingHostCapabilities(fragment);
-            for (Capability hostCap : hostCaps)
-            {
-                Module host = hostCap.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.
-                List<Module> fragments = ((ModuleImpl) host).getFragments();
-                if ((fragments != null) && fragments.contains(fragment))
-                {
-                    List<Module> fragmentList = getMatchingFragments(host);
-
-                    // Remove host's existing exported packages from index.
-                    List<Capability> caps = host.getCapabilities();
-                    removeCapabilities(caps);
-
-                    // 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(null);
-                        }
-                        catch (Exception ex2)
-                        {
-                            // Ignore
-                        }
-                        m_logger.log(host.getBundle(), Logger.LOG_ERROR,
-                            "Serious error attaching fragments.", ex);
-                    }
-
-                    // Reindex the host's exported packages.
-                    caps = host.getCapabilities();
-                    addCapabilities(caps);
-                }
-            }
-        }
-    }
-
-    private void addCapabilities(List<Capability> caps)
-    {
-        if (caps != null)
-        {
-            for (Capability cap : caps)
-            {
-                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                if (capSet == null)
-                {
-                    capSet = new CapabilitySet(null, true);
-                    m_capSets.put(cap.getNamespace(), capSet);
-                }
-                capSet.addCapability(cap);
-            }
-        }
-    }
-
-    private void removeCapabilities(List<Capability> caps)
-    {
-        if (caps != null)
-        {
-            for (Capability cap : caps)
-            {
-                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                if (capSet != null)
-                {
-                    capSet.removeCapability(cap);
-                }
-            }
-        }
-    }
-
-    public void unmergeFragment(Module fragment)
-    {
-        if (!Util.isFragment(fragment))
-        {
-            return;
-        }
-
-        removeFragment(fragment);
-    }
-
-    private Set<Capability> getMatchingHostCapabilities(Module fragment)
-    {
-        // Find the fragment's host requirement.
-        Requirement hostReq = getFragmentHostRequirement(fragment);
-
-        // Create a list of all matching hosts for this fragment.
-        SecurityManager sm = System.getSecurityManager();
-        if ((sm != null) && (fragment.getSymbolicName() != null))
-        {
-            if (!((BundleProtectionDomain) fragment.getSecurityContext()).impliesDirect(
-                new BundlePermission(fragment.getSymbolicName(), BundlePermission.FRAGMENT)))
-            {
-                return new HashSet<Capability>();
-            }
-        }
-
-        Set<Capability> hostCaps =
-            m_capSets.get(Capability.HOST_NAMESPACE).match(hostReq.getFilter(), true);
-
-        for (Iterator<Capability> it = hostCaps.iterator(); it.hasNext(); )
-        {
-            Capability hostCap = it.next();
-
-            // Only look at unresolved hosts, since we don't support
-            // dynamic attachment of fragments.
-// TODO: FELIX3 - This is potentially too narrow, since it won't allow
-//       attaching with updated modules.
-            if (hostCap.getModule().isResolved()
-                || ((BundleImpl) hostCap.getModule().getBundle()).isStale()
-                || ((BundleImpl) hostCap.getModule().getBundle()).isRemovalPending())
-            {
-                it.remove();
-            }
-            else if ((sm != null) && (hostCap.getModule().getSymbolicName() != null))
-            {
-                if (!((BundleProtectionDomain) hostCap.getModule()
-                    .getSecurityContext()).impliesDirect(
-                        new BundlePermission(hostCap.getModule().getSymbolicName(),
-                            BundlePermission.HOST)))
-                {
-                    it.remove();
-                }
-            }
-        }
-
-        return hostCaps;
-    }
-
-    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_modules.add(host);
-        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
-        if (caps.size() > 0)
-        {
-            m_capSets.get(Capability.HOST_NAMESPACE).addCapability(caps.get(0));
-        }
-
-        //
-        // First, merge applicable fragments.
-        //
-
-        List<Module> fragments = getMatchingFragments(host);
-
-        // Attach any fragments we found for this host.
-        if (fragments.size() > 0)
-        {
-            // Attach the fragments to the host.
-            try
-            {
-                ((ModuleImpl) host).attachFragments(fragments);
-            }
-            catch (Exception ex)
-            {
-                // Try to clean up by removing all fragments.
-                try
-                {
-                    ((ModuleImpl) host).attachFragments(null);
-                }
-                catch (Exception ex2)
-                {
-                    // Ignore
-                }
-                m_logger.log(host.getBundle(), Logger.LOG_ERROR,
-                    "Serious error attaching fragments.", ex);
-            }
-        }
-
-        //
-        // Second, index module's capabilities.
-        //
-
-        caps = host.getCapabilities();
-
-        // Add exports to unresolved package map.
-        addCapabilities(caps);
-    }
-
-    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_modules.remove(host);
-        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
-        if (caps.size() > 0)
-        {
-            m_capSets.get(Capability.HOST_NAMESPACE).removeCapability(caps.get(0));
-        }
-
-        // Remove exports from package maps.
-        caps = host.getCapabilities();
-        removeCapabilities(caps);
-
-        // Set fragments to null, which will remove the module from all
-        // of its dependent fragment modules.
-        try
-        {
-            ((ModuleImpl) host).attachFragments(null);
-        }
-        catch (Exception ex)
-        {
-            m_logger.log(
-                host.getBundle(), Logger.LOG_ERROR, "Error detaching fragments.", ex);
-        }
-        // Set wires to null, which will remove the module from all
-        // of its dependent modules.
-        ((ModuleImpl) host).setWires(null);
-    }
-
-    private List<Module> getMatchingFragments(Module host)
-    {
-        // Find the host capability for the current host.
-        List<Capability> caps = Util.getCapabilityByNamespace(host, Capability.HOST_NAMESPACE);
-        Capability hostCap = (caps.isEmpty()) ? null : caps.get(0);
-
-        // If we have a host capability, then loop through all fragments trying to
-        // find ones that match.
-        List<Module> fragmentList = new ArrayList<Module>();
-        SecurityManager sm = System.getSecurityManager();
-        if ((sm != null) && (host.getSymbolicName() != null))
-        {
-            if (!((BundleProtectionDomain) host.getSecurityContext()).impliesDirect(
-                new BundlePermission(host.getSymbolicName(), BundlePermission.HOST)))
-            {
-                return fragmentList;
-            }
-        }
-        for (Iterator it = m_fragmentMap.entrySet().iterator(); (hostCap != null) && it.hasNext(); )
-        {
-            Map.Entry entry = (Map.Entry) it.next();
-            List fragments = (List) entry.getValue();
-            Module fragment = null;
-            for (int i = 0; (fragment == null) && (i < fragments.size()); i++)
-            {
-// TODO: FELIX3 - This is potentially too narrow, since it won't allow
-//       attaching with updated modules.
-                Module f = (Module) fragments.get(i);
-                if (!((BundleImpl) f.getBundle()).isStale()
-                    && !((BundleImpl) f.getBundle()).isRemovalPending())
-                {
-                    fragment = f;
-                }
-            }
-
-            if (fragment == null)
-            {
-                continue;
-            }
-            
-            if ((sm != null) && (fragment.getSymbolicName() != null))
-            {
-                if (!((BundleProtectionDomain) fragment.getSecurityContext()).impliesDirect(
-                    new BundlePermission(fragment.getSymbolicName(), BundlePermission.FRAGMENT)))
-                {
-                    continue;
-                }
-            }
-            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) && CapabilitySet.matches(hostCap, hostReq.getFilter()))
-            {
-                // Now add the new fragment in bundle ID order.
-                int index = -1;
-                for (int listIdx = 0;
-                    (index < 0) && (listIdx < fragmentList.size());
-                    listIdx++)
-                {
-                    Module existing = fragmentList.get(listIdx);
-                    if (fragment.getBundle().getBundleId()
-                        < existing.getBundle().getBundleId())
-                    {
-                        index = listIdx;
-                    }
-                }
-                fragmentList.add(
-                    (index < 0) ? fragmentList.size() : index, fragment);
-            }
-        }
-
-        return fragmentList;
-    }
-
-    public synchronized Module findHost(Module rootModule) throws ResolveException
-    {
-        Module newRootModule = rootModule;
-        if (Util.isFragment(rootModule))
-        {
-            Set<Capability> hostCaps = getMatchingHostCapabilities(rootModule);
-            Module currentBestHost = null;
-            for (Capability hostCap : hostCaps)
-            {
-                Module host = hostCap.getModule();
-                if (currentBestHost == null)
-                {
-                    currentBestHost = host;
-                }
-                else if (currentBestHost.getVersion().compareTo(host.getVersion()) < 0)
-                {
-                    currentBestHost = host;
-                }
-            }
-            newRootModule = currentBestHost;
-
-            if (newRootModule == null)
-            {
-                throw new ResolveException(
-                    "Unable to find host.", rootModule, getFragmentHostRequirement(rootModule));
-            }
-        }
-
-        return newRootModule;
-    }
-
-    private static Requirement getFragmentHostRequirement(Module fragment)
-    {
-        // Find the fragment's host requirement.
-        List<Requirement> reqs = fragment.getRequirements();
-        Requirement hostReq = null;
-        for (int reqIdx = 0; (hostReq == null) && (reqIdx < reqs.size()); reqIdx++)
-        {
-            if (reqs.get(reqIdx).getNamespace().equals(Capability.HOST_NAMESPACE))
-            {
-                hostReq = reqs.get(reqIdx);
-            }
-        }
-        return hostReq;
-    }
-
-    /**
-     * This method is used for installing system bundle extensions. It actually
-     * refreshes the system bundle module's capabilities in the resolver state
-     * to capture additional capabilities.
-     * @param module The module being refresh, which should always be the system bundle.
-    **/
-    synchronized void refreshSystemBundleModule(Module module)
-    {
-        // The system bundle module should always be resolved, so we only need
-        // to update the resolved capability map.
-        List<Capability> caps = module.getCapabilities();
-        addCapabilities(caps);
-    }
-
-    public synchronized void moduleResolved(Module module)
-    {
-        if (module.isResolved())
-        {
-            // Loop through the module's package wires and determine if any
-            // of them overlap any of the packages exported by the module.
-            // If so, then the framework must have chosen to have the module
-            // import rather than export the package, so we need to remove the
-            // corresponding package capability from the package capability set.
-            List<Wire> wires = module.getWires();
-            List<Capability> caps = module.getCapabilities();
-            for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
-            {
-                Wire wire = wires.get(wireIdx);
-                if (wire.getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
-                {
-                    for (int capIdx = 0;
-                        (caps != null) && (capIdx < caps.size());
-                        capIdx++)
-                    {
-                        if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                            && wire.getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue()
-                                .equals(caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue()))
-                        {
-                            m_capSets.get(Capability.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public Set<Capability> getCandidates(Module module, Requirement req, boolean obeyMandatory)
-    {
-        Set<Capability> result = new TreeSet<Capability>(new CandidateComparator());
-
-        CapabilitySet capSet = m_capSets.get(req.getNamespace());
-        if (capSet != null)
-        {
-            Set<Capability> matches = capSet.match(req.getFilter(), obeyMandatory);
-            if (System.getSecurityManager() != null)
-            {
-                for (Capability cap : matches)
-                {
-                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE) && (
-                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                            new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(), 
-                            PackagePermission.EXPORTONLY)) ||
-                            !((module == null) ||
-                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
-                                    new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(), 
-                                    cap.getModule().getBundle(),PackagePermission.IMPORT))
-                            )))
-                    {
-                        if (module != cap.getModule())
-                        {
-                            continue;
-                        }
-                    }
-                    if (req.getNamespace().equals(Capability.MODULE_NAMESPACE) && (
-                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                            new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
-                            !((module == null) ||
-                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
-                                    new BundlePermission(module.getSymbolicName(), BundlePermission.REQUIRE))
-                            )))
-                    {
-                        continue;
-                    }
-
-                    result.add(cap);
-                }
-            }
-            else 
-            {
-                result.addAll(matches);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks to see if the passed in module's required execution environment
-     * is provided by the framework.
-     * @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.
-    **/
-    public void checkExecutionEnvironment(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("")
-                && (m_fwkExecEnvStr != null)
-                && (m_fwkExecEnvStr.length() > 0))
-            {
-                StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
-                boolean found = false;
-                while (tokens.hasMoreTokens() && !found)
-                {
-                    if (m_fwkExecEnvSet.contains(tokens.nextToken().trim()))
-                    {
-                        found = true;
-                    }
-                }
-                if (!found)
-                {
-                    throw new ResolveException(
-                        "Execution environment not supported: "
-                        + bundleExecEnvStr, module, null);
-                }
-            }
-        }
-    }
-
-    public void checkNativeLibraries(Module module) throws ResolveException
-    {
-        // 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.isEmpty())
-            {
-                msg = "No matching native libraries found.";
-            }
-            if (msg != null)
-            {
-                throw new ResolveException(msg, module, null);
-            }
-        }
-    }
-
-    //
-    // Utility methods.
-    //
-
-    /**
-     * 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 fwkExecEnvStr Comma delimited string of provided execution environments
-     * @return the parsed set of execution environments
-    **/
-    private static Set<String> parseExecutionEnvironments(String fwkExecEnvStr)
-    {
-        Set<String> newSet = new HashSet<String>();
-        if (fwkExecEnvStr != null)
-        {
-            StringTokenizer tokens = new StringTokenizer(fwkExecEnvStr, ",");
-            while (tokens.hasMoreTokens())
-            {
-                newSet.add(tokens.nextToken().trim());
-            }
-        }
-        return newSet;
-    }
-
-    /**
-     * 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)
-    {
-        final List<Capability> modCaps =
-            Util.getCapabilityByNamespace(
-                module, Capability.MODULE_NAMESPACE);
-        if (modCaps == null || modCaps.isEmpty())
-        {
-            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()))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static Module indexModule(Map<String, List<Module>> map, Module module)
-    {
-        List<Module> modules = map.get(module.getSymbolicName());
-
-        // We want to add the fragment into the list of matching
-        // fragments in sorted order (descending version and
-        // ascending bundle identifier). Insert using a simple
-        // binary search algorithm.
-        if (modules == null)
-        {
-            modules = new ArrayList<Module>();
-            modules.add(module);
-        }
-        else
-        {
-            Version version = module.getVersion();
-            int top = 0, bottom = modules.size() - 1;
-            while (top <= bottom)
-            {
-                int middle = (bottom - top) / 2 + top;
-                Version middleVersion = modules.get(middle).getVersion();
-                // 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 = modules.get(middle).getBundle().getBundleId();
-                    long exportId = module.getBundle().getBundleId();
-                    if (middleId < exportId)
-                    {
-                        top = middle + 1;
-                    }
-                    else
-                    {
-                        bottom = middle - 1;
-                    }
-                }
-                else
-                {
-                    top = middle + 1;
-                }
-            }
-
-            // Ignore duplicates.
-            if ((top >= modules.size()) || (modules.get(top) != module))
-            {
-                modules.add(top, module);
-            }
-        }
-
-        map.put(module.getSymbolicName(), modules);
-
-        return 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 22f9bf6..d94b8ed 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -38,8 +38,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
-import org.apache.felix.framework.Felix.FelixResolver;
+import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.cache.JarContent;
 import org.apache.felix.framework.capabilityset.Attribute;
 import org.apache.felix.framework.capabilityset.Capability;
@@ -72,7 +74,7 @@
 {
     private final Logger m_logger;
     private final Map m_configMap;
-    private final FelixResolver m_resolver;
+    private final StatefulResolver m_resolver;
     private final String m_id;
     private final Content m_content;
     private final Map m_headerMap;
@@ -201,7 +203,7 @@
     }
 
     public ModuleImpl(
-        Logger logger, Map configMap, FelixResolver resolver,
+        Logger logger, Map configMap, StatefulResolver resolver,
         Bundle bundle, String id, Map headerMap, Content content,
         URLStreamHandler streamHandler, String[] bootPkgs,
         boolean[] bootPkgWildcards)
@@ -473,10 +475,20 @@
 
     public synchronized void setWires(List<Wire> wires)
     {
+        // This not only sets the wires for the module, but it also records
+        // the dependencies this module has on other modules (i.e., the provider
+        // end of the wire) to simplify bookkeeping.
+
+        // Fragments don't depend on other their hosts, so we just record the
+        // wires for informational purposes.
+// TODO: FRAGMENT RESOLVER - It is possible for a fragment to get more wires
+//       later if it is attached to more hosts. We need to deal with that.
+        boolean isFragment = Util.isFragment(this);
+
         // 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.size()); i++)
+        for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
         {
             if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
@@ -491,7 +503,7 @@
         m_wires = wires;
 
         // Add ourself as a dependent to the new wires' modules.
-        for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
+        for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
         {
             if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
             {
@@ -514,6 +526,27 @@
         m_isResolved = true;
     }
 
+
+    public synchronized void setSecurityContext(Object securityContext)
+    {
+        m_protectionDomain = (ProtectionDomain) securityContext;
+    }
+
+    public synchronized Object getSecurityContext()
+    {
+        return m_protectionDomain;
+    }
+
+    // TODO: FRAGMENT RESOLVER - Technically, this is only necessary for fragments.
+    //       When we refactoring for the new R4.3 framework API, we'll have to see
+    //       if this is still necessary, since the new BundleWirings API will give
+    //       us another way to detect it.
+    public boolean isRemovalPending()
+    {
+        return (m_bundle.getState() == Bundle.UNINSTALLED)
+            || (this != ((BundleImpl) m_bundle).getCurrentModule());
+    }
+
     //
     // Content access methods.
     //
@@ -623,7 +656,7 @@
 
         // If there is nothing on the class path, then include
         // "." by default, as per the spec.
-        if (localContentList.size() == 0)
+        if (localContentList.isEmpty())
         {
             localContentList.add(content);
         }
@@ -1156,6 +1189,25 @@
             ((ModuleImpl) m_fragments.get(i)).removeDependentHost(this);
         }
 
+        // Close previous fragment contents.
+        for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+        {
+            m_fragmentContents[i].close();
+        }
+        m_fragmentContents = null;
+
+        // Close the old content path, since we'll need to recalculate it for
+        // for the added (or removed) fragments.
+        for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+        {
+            // Don't close this module's content, if it is on the content path.
+            if (m_content != m_contentPath[i])
+            {
+                m_contentPath[i].close();
+            }
+        }
+        m_contentPath = null;
+
         // Remove cached capabilities and requirements.
         m_cachedCapabilities = null;
         m_cachedRequirements = null;
@@ -1164,48 +1216,37 @@
         // Update the dependencies on the new fragments.
         m_fragments = fragments;
 
-        // We need to add ourself as a dependent of each fragment
-        // module. We also need to create an array of fragment contents
-        // to attach to our content loader.
+        // We need to sort the fragments and add ourself as a dependent of each one.
+        // We also need to create an array of fragment contents to attach to our
+        // content path.
         if (m_fragments != null)
         {
-            Content[] fragmentContents = new Content[m_fragments.size()];
+            // Sort fragments according to ID order, if necessary.
+            // Note that this sort order isn't 100% correct since
+            // it uses a string, but it is likely close enough and
+            // avoids having to create more objects.
+            if (m_fragments.size() > 1)
+            {
+                SortedMap<String, Module> sorted = new TreeMap<String, Module>();
+                for (Module f : m_fragments)
+                {
+                    sorted.put(f.getId(), f);
+                }
+                m_fragments = new ArrayList(sorted.values());
+            }
+            m_fragmentContents = new Content[m_fragments.size()];
             for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
             {
                 ((ModuleImpl) m_fragments.get(i)).addDependentHost(this);
-                fragmentContents[i] =
+                m_fragmentContents[i] =
                     m_fragments.get(i).getContent()
                         .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
             }
-            // Now attach the fragment contents to our content loader.
-            attachFragmentContents(fragmentContents);
+            // Recalculate the content path for the new fragments.
+            m_contentPath = initializeContentPath();
         }
     }
 
-    // This must be called holding the object lock.
-    private void attachFragmentContents(Content[] fragmentContents)
-        throws Exception
-    {
-        // Close existing fragment contents.
-        if (m_fragmentContents != null)
-        {
-            for (int i = 0; i < m_fragmentContents.length; i++)
-            {
-                m_fragmentContents[i].close();
-            }
-        }
-        m_fragmentContents = fragmentContents;
-
-        if (m_contentPath != null)
-        {
-            for (int i = 0; i < m_contentPath.length; i++)
-            {
-                m_contentPath[i].close();
-            }
-        }
-        m_contentPath = initializeContentPath();
-    }
-
     public synchronized List<Module> getDependentHosts()
     {
         return m_dependentHosts;
@@ -1277,23 +1318,15 @@
         {
             m_contentPath[i].close();
         }
+        m_contentPath = null;
         for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
         {
             m_fragmentContents[i].close();
         }
+        m_fragmentContents = null;
         m_classLoader = null;
     }
 
-    public synchronized void setSecurityContext(Object securityContext)
-    {
-        m_protectionDomain = (ProtectionDomain) securityContext;
-    }
-
-    public synchronized Object getSecurityContext()
-    {
-        return m_protectionDomain;
-    }
-
     public String toString()
     {
         return m_id;
@@ -2150,7 +2183,7 @@
     }
 
     private static String diagnoseClassLoadError(
-        FelixResolver resolver, ModuleImpl module, String name)
+        StatefulResolver resolver, ModuleImpl module, String name)
     {
         // We will try to do some diagnostics here to help the developer
         // deal with this exception.
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
new file mode 100644
index 0000000..7143fb6
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.resolver.CandidateComparator;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.Resolver;
+import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.osgi.framework.BundlePermission;
+import org.osgi.framework.Constants;
+import org.osgi.framework.PackagePermission;
+
+class ResolverStateImpl implements Resolver.ResolverState
+{
+    private final Logger m_logger;
+    // Set of all modules.
+    private final Set<Module> m_modules;
+    // Set of all fragments.
+    private final Set<Module> m_fragments;
+    // Capability sets.
+    private final Map<String, CapabilitySet> m_capSets;
+    // Execution environment.
+    private final String m_fwkExecEnvStr;
+    // Parsed framework environments
+    private final Set<String> m_fwkExecEnvSet;
+
+    ResolverStateImpl(Logger logger, String fwkExecEnvStr)
+    {
+        m_logger = logger;
+        m_modules = new HashSet<Module>();
+        m_fragments = new HashSet<Module>();
+        m_capSets = new HashMap<String, CapabilitySet>();
+
+        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
+        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
+
+        List<String> indices = new ArrayList<String>();
+        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+        m_capSets.put(Capability.MODULE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(Capability.PACKAGE_ATTR);
+        m_capSets.put(Capability.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
+        m_capSets.put(Capability.HOST_NAMESPACE,  new CapabilitySet(indices, true));
+    }
+
+    synchronized void addModule(Module m)
+    {
+        m_modules.add(m);
+        List<Capability> caps = m.getCapabilities();
+        if (caps != null)
+        {
+            for (Capability cap : caps)
+            {
+                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+                if (capSet == null)
+                {
+                    capSet = new CapabilitySet(null, true);
+                    m_capSets.put(cap.getNamespace(), capSet);
+                }
+                capSet.addCapability(cap);
+            }
+        }
+
+        if (Util.isFragment(m))
+        {
+            m_fragments.add(m);
+        }
+    }
+
+    synchronized void removeModule(Module m)
+    {
+        m_modules.remove(m);
+        List<Capability> caps = m.getCapabilities();
+        if (caps != null)
+        {
+            for (Capability cap : caps)
+            {
+                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+                if (capSet != null)
+                {
+                    capSet.removeCapability(cap);
+                }
+            }
+        }
+
+        if (Util.isFragment(m))
+        {
+            m_fragments.remove(m);
+        }
+    }
+
+    synchronized Set<Module> getFragments()
+    {
+        return new HashSet(m_fragments);
+    }
+
+    synchronized void removeSubstitutedCapabilities(Module module)
+    {
+        if (module.isResolved())
+        {
+            // Loop through the module's package wires and determine if any
+            // of them overlap any of the packages exported by the module.
+            // If so, then the framework must have chosen to have the module
+            // import rather than export the package, so we need to remove the
+            // corresponding package capability from the package capability set.
+            List<Wire> wires = module.getWires();
+            List<Capability> caps = module.getCapabilities();
+            for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
+            {
+                Wire wire = wires.get(wireIdx);
+                if (wire.getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                {
+                    for (int capIdx = 0;
+                        (caps != null) && (capIdx < caps.size());
+                        capIdx++)
+                    {
+                        if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                            && wire.getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue()
+                                .equals(caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue()))
+                        {
+                            m_capSets.get(Capability.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    //
+    // ResolverState methods.
+    //
+
+    public synchronized SortedSet<Capability> getCandidates(
+        Module module, Requirement req, boolean obeyMandatory)
+    {
+        SortedSet<Capability> result = new TreeSet<Capability>(new CandidateComparator());
+
+        CapabilitySet capSet = m_capSets.get(req.getNamespace());
+        if (capSet != null)
+        {
+            Set<Capability> matches = capSet.match(req.getFilter(), obeyMandatory);
+            for (Capability cap : matches)
+            {
+                if (System.getSecurityManager() != null)
+                {
+                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE) && (
+                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+                            new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                            PackagePermission.EXPORTONLY)) ||
+                            !((module == null) ||
+                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+                                    new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                                    cap.getModule().getBundle(),PackagePermission.IMPORT))
+                            )))
+                    {
+                        if (module != cap.getModule())
+                        {
+                            continue;
+                        }
+                    }
+                    else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE) && (
+                        !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
+                            new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
+                            !((module == null) ||
+                                ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
+                                    new BundlePermission(module.getSymbolicName(), BundlePermission.REQUIRE))
+                            )))
+                    {
+                        continue;
+                    }
+                }
+                else if (req.getNamespace().equals(Capability.HOST_NAMESPACE)
+                    && cap.getModule().isResolved())
+                {
+                    continue;
+                }
+
+                result.add(cap);
+            }
+        }
+
+        return result;
+    }
+
+    public void checkExecutionEnvironment(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("")
+                && (m_fwkExecEnvStr != null)
+                && (m_fwkExecEnvStr.length() > 0))
+            {
+                StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
+                boolean found = false;
+                while (tokens.hasMoreTokens() && !found)
+                {
+                    if (m_fwkExecEnvSet.contains(tokens.nextToken().trim()))
+                    {
+                        found = true;
+                    }
+                }
+                if (!found)
+                {
+                    throw new ResolveException(
+                        "Execution environment not supported: "
+                        + bundleExecEnvStr, module, null);
+                }
+            }
+        }
+    }
+
+    public void checkNativeLibraries(Module module) throws ResolveException
+    {
+        // 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.isEmpty())
+            {
+                msg = "No matching native libraries found.";
+            }
+            if (msg != null)
+            {
+                throw new ResolveException(msg, module, null);
+            }
+        }
+    }
+
+    //
+    // Utility methods.
+    //
+
+    /**
+     * 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 fwkExecEnvStr Comma delimited string of provided execution environments
+     * @return the parsed set of execution environments
+    **/
+    private static Set<String> parseExecutionEnvironments(String fwkExecEnvStr)
+    {
+        Set<String> newSet = new HashSet<String>();
+        if (fwkExecEnvStr != null)
+        {
+            StringTokenizer tokens = new StringTokenizer(fwkExecEnvStr, ",");
+            while (tokens.hasMoreTokens())
+            {
+                newSet.add(tokens.nextToken().trim());
+            }
+        }
+        return newSet;
+    }
+}
\ 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
index e718b49..c8957f9 100644
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -36,7 +36,7 @@
 public class CapabilitySet
 {
     private final Map<String, Map<Object, Set<Capability>>> m_indices;
-    private final Set<Capability> m_capList = new HashSet<Capability>();
+    private final Set<Capability> m_capSet = new HashSet<Capability>();
     private final static SecureAction m_secureAction = new SecureAction();
 
     public CapabilitySet(List<String> indexProps, boolean caseSensitive)
@@ -52,7 +52,7 @@
 
     public void addCapability(Capability cap)
     {
-        m_capList.add(cap);
+        m_capSet.add(cap);
 
         // Index capability.
         for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
@@ -98,7 +98,7 @@
 
     public void removeCapability(Capability cap)
     {
-        if (m_capList.remove(cap))
+        if (m_capSet.remove(cap))
         {
             for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
             {
@@ -146,7 +146,7 @@
 
     public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
     {
-        Set<Capability> matches = match(m_capList, sf);
+        Set<Capability> matches = match(m_capSet, sf);
         return (obeyMandatory)
             ? matchMandatory(matches, sf)
             : matches;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
new file mode 100644
index 0000000..9f336a5
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -0,0 +1,495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.osgi.framework.Version;
+
+public class Candidates
+{
+    private final Module m_root;
+
+    // Maps a capability to requirements that match it.
+    private final Map<Capability, Set<Requirement>> m_dependentMap;
+    // Maps a requirement to the capability it matches.
+    private final Map<Requirement, SortedSet<Capability>> m_candidateMap;
+    // Maps a module to a map containing its potential fragments; the
+    // fragment map maps a fragment symbolic name to a map that maps
+    // a version to a list of fragments matching that symbolic name
+    // and version.
+    private final Map<Module, Map<String, Map<Version, List<Module>>>> m_hostFragments;
+    // Maps a module to its associated wrapped module; this only happens
+    // when a module being resolved has fragments to attach to it.
+    private final Map<Module, WrappedModule> m_allWrappedHosts;
+
+    /**
+     * Private copy constructor used by the copy() method.
+     * @param root the root module for the resolve.
+     * @param dependentMap the capability dependency map.
+     * @param candidateMap the requirement candidate map.
+     * @param hostFragments the fragment map.
+     * @param wrappedHosts the wrapped hosts map.
+    **/
+    private Candidates(
+        Module root,
+        Map<Capability, Set<Requirement>> dependentMap,
+        Map<Requirement, SortedSet<Capability>> candidateMap,
+        Map<Module, Map<String, Map<Version, List<Module>>>> hostFragments,
+        Map<Module, WrappedModule> wrappedHosts)
+    {
+        m_root = root;
+        m_dependentMap = dependentMap;
+        m_candidateMap = candidateMap;
+        m_hostFragments = hostFragments;
+        m_allWrappedHosts = wrappedHosts;
+    }
+
+    /**
+     * Constructs a new object with the specified root module. The root module
+     * is used to determine if the resolves fails when manipulating the candidates.
+     * For example, it may be necessary to remove an unselected fragment, which
+     * can cause a ripple effect all the way to the root module. If that happens
+     * then the resolve fails.
+     * @param root the root module for the resolve.
+    **/
+    public Candidates(Module root)
+    {
+        m_root = root;
+        m_dependentMap = new HashMap<Capability, Set<Requirement>>();
+        m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
+        m_hostFragments = new HashMap<Module, Map<String, Map<Version, List<Module>>>>();
+        m_allWrappedHosts = new HashMap<Module, WrappedModule>();
+    }
+
+    /**
+     * Adds a requirement and its matching candidates to the internal data
+     * structure. This method assumes it owns the data being passed in and
+     * does not make a copy. It takes the data and processes, such as calculating
+     * which requirements depend on which capabilities and recording any fragments
+     * it finds for future merging.
+     * @param req the requirement to add.
+     * @param candidates the candidates matching the requirement.
+    **/
+    public void add(Requirement req, SortedSet<Capability> candidates)
+    {
+        boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
+
+        // Record the candidates.
+        m_candidateMap.put(req, candidates);
+        // Add the requirement as a dependent on the candidates.
+        for (Capability cap : candidates)
+        {
+            Set<Requirement> dependents = m_dependentMap.get(cap);
+            if (dependents == null)
+            {
+                dependents = new HashSet<Requirement>();
+                m_dependentMap.put(cap, dependents);
+            }
+            dependents.add(req);
+            // Keep track of hosts and associated fragments.
+            if (isFragment)
+            {
+                Map<String, Map<Version, List<Module>>> fragments =
+                    m_hostFragments.get(cap.getModule());
+                if (fragments == null)
+                {
+                    fragments = new HashMap<String, Map<Version, List<Module>>>();
+                    m_hostFragments.put(cap.getModule(), fragments);
+                }
+                Map<Version, List<Module>> fragmentVersions =
+                    fragments.get(req.getModule().getSymbolicName());
+                if (fragmentVersions == null)
+                {
+                    fragmentVersions = new TreeMap<Version, List<Module>>(Collections.reverseOrder());
+                    fragments.put(req.getModule().getSymbolicName(), fragmentVersions);
+                }
+                List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+                if (actual == null)
+                {
+                    actual = new ArrayList<Module>();
+                    fragmentVersions.put(req.getModule().getVersion(), actual);
+                }
+                actual.add(req.getModule());
+            }
+        }
+    }
+
+    /**
+     * Adds requirements and candidates in bulk. The outer map is not retained
+     * by this method, but the inner data structures are, so they should not
+     * be further modified by the caller.
+     * @param candidates the bulk requirements and candidates to add.
+    **/
+    public void add(Map<Requirement, SortedSet<Capability>> candidates)
+    {
+        for (Entry<Requirement, SortedSet<Capability>> entry : candidates.entrySet())
+        {
+            add(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Returns the wrapped module associated with the given module. If the module
+     * was not wrapped, then the module itself is returned. This is really only
+     * needed to determine if the root modules of the resolve have been wrapped.
+     * @param m the module whose wrapper is desired.
+     * @return the wrapper module or the module itself if it was not wrapped.
+    **/
+    public Module getWrappedHost(Module m)
+    {
+        Module wrapped = m_allWrappedHosts.get(m);
+        return (wrapped == null) ? m : wrapped;
+    }
+
+    /**
+     * Gets the candidates associated with a given requirement.
+     * @param req the requirement whose candidates are desired.
+     * @return the matching candidates or null.
+    **/
+    public SortedSet<Capability> getCandidates(Requirement req)
+    {
+        return m_candidateMap.get(req);
+    }
+
+    /**
+     * Gets the complete candidate map. This is only used in the dynamic
+     * import case, since the requirement is unknown and it just needs the
+     * one and only requirement in the map. (This could probably be handled
+     * differently or better, but it is sufficient for now.)
+     * @return The entire candidate map.
+    **/
+    public Map<Requirement, SortedSet<Capability>> getCandidateMap()
+    {
+        return m_candidateMap;
+    }
+
+    /**
+     * Merges fragments into their hosts. It does this by wrapping all host
+     * modules and attaching their selected fragments, removing all unselected
+     * fragment modules, and replacing all occurrences of the original fragments
+     * in the internal data structures with the wrapped host modules instead.
+     * Thus, fragment capabilities and requirements are merged into the appropriate
+     * host and the candidates for the fragment now become candidates for the host.
+     * Likewise, any module depending on a fragment now depend on the host. Note
+     * that this process is sort of like multiplication, since one fragment that
+     * can attach to two hosts effectively gets multiplied across the two hosts.
+     * So, any modules being satisfied by the fragment will end up having the
+     * two hosts as potential candidates, rather than the single fragment.
+    **/
+    public void mergeFragments()
+    {
+        // This method performs the following steps:
+        // 1. Select the fragments to attach to a given host.
+        // 2. Wrap hosts and attach fragments.
+        // 3. Remove any unselected fragments. This is necessary because
+        //    other modules may depend on the capabilities of unselected
+        //    fragments, so we need to remove the unselected fragments and
+        //    any module that depends on them, which could ultimately cause
+        //    the entire resolve to fail.
+        // 4. Replace all fragments with any host it was merged into
+        //    (effectively multiplying it).
+        //    * This includes setting candidates for attached fragment
+        //      requirements as well as replacing fragment capabilities
+        //      with host's attached fragment capabilities.
+
+        // Steps 1 and 2
+        List<WrappedModule> wrappedHosts = new ArrayList<WrappedModule>();
+        List<Module> unselectedFragments = new ArrayList<Module>();
+        for (Entry<Module, Map<String, Map<Version, List<Module>>>> entry :
+            m_hostFragments.entrySet())
+        {
+            // Step 1
+            List<Module> selectedFragments = new ArrayList<Module>();
+            Module host = entry.getKey();
+            Map<String, Map<Version, List<Module>>> fragments = entry.getValue();
+            for (Entry<String, Map<Version, List<Module>>> fragEntry : fragments.entrySet())
+            {
+                boolean isFirst = true;
+                for (Entry<Version, List<Module>> versionEntry : fragEntry.getValue().entrySet())
+                {
+                    for (Module m : versionEntry.getValue())
+                    {
+                        if (isFirst && !m.isRemovalPending())
+                        {
+                            selectedFragments.add(m);
+                            isFirst = false;
+                        }
+                        else
+                        {
+                            unselectedFragments.add(m);
+                        }
+                    }
+                }
+            }
+
+            // Step 2
+            WrappedModule wrappedHost = new WrappedModule(host, selectedFragments);
+            wrappedHosts.add(wrappedHost);
+            m_allWrappedHosts.put(host, wrappedHost);
+        }
+
+        // Step 3
+        for (Module m : unselectedFragments)
+        {
+            unselectFragment(m);
+        }
+
+        // Step 4
+        for (WrappedModule wrappedHost : wrappedHosts)
+        {
+            // Replaces capabilities from fragments with the capabilities
+            // from the merged host.
+            for (Capability c : wrappedHost.getCapabilities())
+            {
+                Set<Requirement> dependents =
+                    m_dependentMap.get(((WrappedCapability) c).getWrappedCapability());
+                if (dependents != null)
+                {
+                    for (Requirement r : dependents)
+                    {
+                        Set<Capability> cands = m_candidateMap.get(r);
+                        cands.remove(((WrappedCapability) c).getWrappedCapability());
+                        cands.add(c);
+                    }
+                }
+            }
+
+            // Copies candidates for fragment requirements to the host.
+            // This doesn't record the reverse dependency, but that
+            // information should not be needed at this point anymore.
+            for (Requirement r : wrappedHost.getRequirements())
+            {
+                SortedSet<Capability> cands =
+                    m_candidateMap.get(((WrappedRequirement) r).getWrappedRequirement());
+                if (cands != null)
+                {
+                    m_candidateMap.put(r, new TreeSet<Capability>(cands));
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a fragment from the internal data structures if it wasn't selected.
+     * This process may cause other modules to become unresolved if they depended
+     * on fragment capabilities and there is no other candidate.
+     * @param fragment the fragment to remove.
+     * @throws ResolveException if removing the fragment caused the resolve to fail.
+    **/
+    private void unselectFragment(Module fragment) throws ResolveException
+    {
+        Set<Module> unresolvedModules = new HashSet<Module>();
+        remove(fragment, unresolvedModules);
+        while (!unresolvedModules.isEmpty())
+        {
+            Iterator<Module> it = unresolvedModules.iterator();
+            fragment = it.next();
+            it.remove();
+            remove(fragment, unresolvedModules);
+        }
+    }
+
+    /**
+     * Removes the specified module from the internal data structures, which
+     * involves removing its requirements and its capabilities. This may cause
+     * other modules to become unresolved as a result.
+     * @param m the module to remove.
+     * @param unresolvedModules a list to containing any additional modules that
+     *        that became unresolved as a result of removing this module and will
+     *        also need to be removed.
+     * @throws ResolveException if removing the module caused the resolve to fail.
+    **/
+    private void remove(Module m, Set<Module> unresolvedModules) throws ResolveException
+    {
+        for (Requirement r : m.getRequirements())
+        {
+            remove(r);
+        }
+
+        for (Capability c : m.getCapabilities())
+        {
+            remove(c, unresolvedModules);
+        }
+    }
+
+    /**
+     * Removes a requirement from the internal data structures.
+     * @param req the requirement to remove.
+    **/
+    private void remove(Requirement req)
+    {
+        boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
+
+        SortedSet<Capability> candidates = m_candidateMap.remove(req);
+        if (candidates != null)
+        {
+            for (Capability cap : candidates)
+            {
+                Set<Requirement> dependents = m_dependentMap.get(cap);
+                if (dependents != null)
+                {
+                    dependents.remove(req);
+                }
+
+                if (isFragment)
+                {
+                    Map<String, Map<Version, List<Module>>> fragments =
+                        m_hostFragments.get(cap.getModule());
+                    if (fragments != null)
+                    {
+                        Map<Version, List<Module>> fragmentVersions =
+                            fragments.get(req.getModule().getSymbolicName());
+                        if (fragmentVersions != null)
+                        {
+                            List<Module> actual = fragmentVersions.get(req.getModule().getVersion());
+                            if (actual != null)
+                            {
+                                actual.remove(req.getModule());
+                                if (actual.isEmpty())
+                                {
+                                    fragmentVersions.remove(req.getModule().getVersion());
+                                    if (fragmentVersions.isEmpty())
+                                    {
+                                        fragments.remove(req.getModule().getSymbolicName());
+                                        if (fragments.isEmpty())
+                                        {
+                                            m_hostFragments.remove(cap.getModule());
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a capability from the internal data structures. This may cause
+     * other modules to become unresolved as a result.
+     * @param c the capability to remove.
+     * @param unresolvedModules a list to containing any additional modules that
+     *        that became unresolved as a result of removing this module and will
+     *        also need to be removed.
+     * @throws ResolveException if removing the module caused the resolve to fail.
+    **/
+    private void remove(Capability c, Set<Module> unresolvedModules) throws ResolveException
+    {
+        Set<Requirement> dependents = m_dependentMap.remove(c);
+        if (dependents != null)
+        {
+            for (Requirement r : dependents)
+            {
+                SortedSet<Capability> candidates = m_candidateMap.get(r);
+                candidates.remove(c);
+                if (candidates.isEmpty())
+                {
+                    m_candidateMap.remove(r);
+                    if (!r.isOptional())
+                    {
+                        if (m_root.equals(r.getModule()))
+                        {
+                            String msg = "Unable to resolve " + m_root
+                                + ": missing requirement " + r;
+                            ResolveException ex = new ResolveException(msg, m_root, r);
+                            throw ex;
+                        }
+                        unresolvedModules.add(r.getModule());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a copy of the Candidates object. This is used for creating
+     * permutations when package space conflicts are discovered.
+     * @return copy of this Candidates object.
+    **/
+    public Candidates copy()
+    {
+        Map<Capability, Set<Requirement>> dependentMap =
+            new HashMap<Capability, Set<Requirement>>();
+        for (Entry<Capability, Set<Requirement>> entry : m_dependentMap.entrySet())
+        {
+            Set<Requirement> dependents = new HashSet<Requirement>(entry.getValue());
+            dependentMap.put(entry.getKey(), dependents);
+        }
+
+        Map<Requirement, SortedSet<Capability>> candidateMap =
+            new HashMap<Requirement, SortedSet<Capability>>();
+        for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
+        {
+            SortedSet<Capability> candidates = new TreeSet<Capability>(entry.getValue());
+            candidateMap.put(entry.getKey(), candidates);
+        }
+
+        return new Candidates(
+            m_root, dependentMap, candidateMap, m_hostFragments, m_allWrappedHosts);
+    }
+
+    public void dump()
+    {
+        // Create set of all modules from requirements.
+        Set<Module> modules = new HashSet();
+        for (Entry<Requirement, SortedSet<Capability>> entry
+            : m_candidateMap.entrySet())
+        {
+            modules.add(entry.getKey().getModule());
+        }
+        // Now dump the modules.
+        System.out.println("=== BEGIN CANDIDATE MAP ===");
+        for (Module module : modules)
+        {
+            System.out.println("  " + module
+                 + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
+            for (Requirement req : module.getRequirements())
+            {
+                Set<Capability> candidates = m_candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+            for (Requirement req : module.getDynamicRequirements())
+            {
+                Set<Capability> candidates = m_candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+        }
+        System.out.println("=== END CANDIDATE MAP ===");
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
index 695bfd3..7d9f84f 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
@@ -52,6 +52,11 @@
     List<Wire> getWires();
     boolean isResolved();
     Object getSecurityContext();
+    // TODO: FRAGMENT RESOLVER - Technically, this is only necessary for fragments.
+    //       When we refactoring for the new R4.3 framework API, we'll have to see
+    //       if this is still necessary, since the new BundleWirings API will give
+    //       us another way to detect it.
+    boolean isRemovalPending();
 
     // Content access methods.
     Content getContent();
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
index d6f2c24..2d8f9e0 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -21,17 +21,20 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedSet;
 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);
+    Map<Module, List<Wire>> resolve(ResolverState state, Module module, Set<Module> fragments);
+    Map<Module, List<Wire>> resolve(
+        ResolverState state, Module module, String pkgName, Set<Module> fragments);
 
     public static interface ResolverState
     {
-        Set<Capability> getCandidates(Module module, Requirement req, boolean obeyMandatory);
+        SortedSet<Capability> getCandidates(
+            Module module, Requirement req, boolean obeyMandatory);
         void checkExecutionEnvironment(Module module) throws ResolveException;
         void checkNativeLibraries(Module module) throws ResolveException;
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index 7c7e409..9034ccb 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -27,7 +27,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.TreeSet;
+import java.util.SortedSet;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.Attribute;
 import org.apache.felix.framework.capabilityset.Capability;
@@ -44,90 +44,152 @@
 
     // Holds candidate permutations based on permutating "uses" chains.
     // These permutations are given higher priority.
-    private final List<Map<Requirement, Set<Capability>>> m_usesPermutations =
-        new ArrayList<Map<Requirement, Set<Capability>>>();
+    private final List<Candidates> m_usesPermutations = new ArrayList<Candidates>();
     // Holds candidate permutations based on permutating requirement candidates.
     // These permutations represent backtracking on previous decisions.
-    private final List<Map<Requirement, Set<Capability>>> m_importPermutations =
-        new ArrayList<Map<Requirement, Set<Capability>>>();
+    private final List<Candidates> m_importPermutations = new ArrayList<Candidates>();
 
     public ResolverImpl(Logger logger)
     {
         m_logger = logger;
     }
 
-    public Map<Module, List<Wire>> resolve(ResolverState state, Module module)
+    public Map<Module, List<Wire>> resolve(
+        ResolverState state, Module module, Set<Module> fragments)
     {
         Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
-
         Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
 
         if (!module.isResolved())
         {
-            try
+            boolean retryFragments;
+            do
             {
-                Map<Requirement, Set<Capability>> candidateMap =
-                    new HashMap<Requirement, Set<Capability>>();
+                retryFragments = false;
 
-                populateCandidates(
-                    state, module, candidateMap, new HashMap<Module, Object>());
-                m_usesPermutations.add(candidateMap);
-
-                ResolveException rethrow = null;
-
-                do
+                try
                 {
-                    rethrow = null;
+                    Candidates allCandidates = new Candidates(module);
 
-                    modulePkgMap.clear();
-                    m_packageSourcesCache.clear();
+                    // Populate all candidates.
+                    Map<Module, Object> resultCache = new HashMap<Module, Object>();
+                    populateCandidates(
+                        state, module, allCandidates, resultCache);
 
-                    candidateMap = (m_usesPermutations.size() > 0)
-                        ? m_usesPermutations.remove(0)
-                        : m_importPermutations.remove(0);
-//dumpCandidateMap(candidateMap);
+                    // Try to populate optional fragments.
+                    for (Module fragment : fragments)
+                    {
+                        try
+                        {
+                            populateCandidates(state, fragment, allCandidates, resultCache);
+                        }
+                        catch (ResolveException ex)
+                        {
+                            // Ignore, since fragments are optional.
+                         }
+                    }
 
-                    calculatePackageSpaces(
-                        module, candidateMap, modulePkgMap,
-                        new HashMap(), new HashSet());
+                    // Merge any fragments into hosts.
+                    allCandidates.mergeFragments();
+
+                    // Record the initial candidate permutation.
+                     m_usesPermutations.add(allCandidates);
+
+                    ResolveException rethrow = null;
+
+                    // If the requested module is a fragment, then
+                    // ultimately we will verify the host.
+                    Requirement hostReq = getHostRequirement(module);
+                    Module target = module;
+
+                    do
+                    {
+                        rethrow = null;
+
+                        modulePkgMap.clear();
+                        m_packageSourcesCache.clear();
+
+                        allCandidates = (m_usesPermutations.size() > 0)
+                            ? m_usesPermutations.remove(0)
+                            : m_importPermutations.remove(0);
+//allCandidates.dump();
+
+                        // If we are resolving a fragment, then we
+                        // actually want to verify its host.
+                        if (hostReq != null)
+                        {
+                            target = allCandidates.getCandidates(hostReq)
+                                .iterator().next().getModule();
+                        }
+
+                        calculatePackageSpaces(
+                            allCandidates.getWrappedHost(target), allCandidates, modulePkgMap,
+                            new HashMap(), new HashSet());
 //System.out.println("+++ PACKAGE SPACES START +++");
 //dumpModulePkgMap(modulePkgMap);
 //System.out.println("+++ PACKAGE SPACES END +++");
 
-                    try
-                    {
-                        checkPackageSpaceConsistency(
-                            false, module, candidateMap, modulePkgMap, new HashMap());
+                        try
+                        {
+                            checkPackageSpaceConsistency(
+                                false, allCandidates.getWrappedHost(target),
+                                allCandidates, modulePkgMap, new HashMap());
+                        }
+                        catch (ResolveException ex)
+                        {
+                            rethrow = ex;
+                        }
                     }
-                    catch (ResolveException ex)
+                    while ((rethrow != null)
+                        && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
+
+                    // If there is a resolve exception, then determine if an
+                    // optionally resolved module is to blame (typically a fragment).
+                    // If so, then remove the optionally resolved module and try
+                    // again; otherwise, rethrow the resolve exception.
+                    if (rethrow != null)
                     {
-                        rethrow = ex;
+                        Module faultyModule = getActualModule(rethrow.getModule());
+                        if (rethrow.getRequirement() instanceof WrappedRequirement)
+                        {
+                            faultyModule =
+                                ((WrappedRequirement) rethrow.getRequirement())
+                                    .getWrappedRequirement().getModule();
+                        }
+                        if (fragments.remove(faultyModule))
+                        {
+                            retryFragments = true;
+                        }
+                        else
+                        {
+                            throw rethrow;
+                        }
+                    }
+                    // If there is no exception to rethrow, then this was a clean
+                    // resolve, so populate the wire map.
+                    else
+                    {
+                        wireMap =
+                            populateWireMap(
+                                allCandidates.getWrappedHost(target),
+                                modulePkgMap, wireMap, allCandidates);
                     }
                 }
-                while ((rethrow != null)
-                    && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
-
-                if (rethrow != null)
+                finally
                 {
-                    throw rethrow;
+                    // Always clear the state.
+                    m_usesPermutations.clear();
+                    m_importPermutations.clear();
                 }
-
-                wireMap =
-                    populateWireMap(module, modulePkgMap, wireMap,
-                    candidateMap);
             }
-            finally
-            {
-                // Always clear the state.
-                m_usesPermutations.clear();
-                m_importPermutations.clear();
-            }
+            while (retryFragments);
         }
 
         return wireMap;
     }
 
-    public Map<Module, List<Wire>> resolve(ResolverState state, Module module, String pkgName)
+    public Map<Module, List<Wire>> resolve(
+        ResolverState state, Module module, String pkgName, Set<Module> fragments)
     {
         // We can only create a dynamic import if the following
         // conditions are met:
@@ -138,71 +200,157 @@
         // 5. The package in question matches a dynamic import of the bundle.
         // The following call checks all of these conditions and returns
         // the associated dynamic import and matching capabilities.
-        Map<Requirement, Set<Capability>> candidateMap =
+        Candidates allCandidates =
             getDynamicImportCandidates(state, module, pkgName);
-        if (candidateMap != null)
+        if (allCandidates != null)
         {
-            try
+            Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+            Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
+
+            boolean retryFragments;
+            do
             {
-                Map<Module, List<Wire>> wireMap = new HashMap();
-                Map<Module, Packages> modulePkgMap = new HashMap();
+                retryFragments = false;
 
-                populateDynamicCandidates(state, module, candidateMap);
-                m_usesPermutations.add(candidateMap);
-
-                ResolveException rethrow = null;
-
-                do
+                try
                 {
-                    rethrow = null;
+                    // Populate all candidates.
+                    Map<Module, Object> resultCache = new HashMap<Module, Object>();
+                    populateDynamicCandidates(state, module, allCandidates, resultCache);
 
-                    modulePkgMap.clear();
-
-                    candidateMap = (m_usesPermutations.size() > 0)
-                        ? m_usesPermutations.remove(0)
-                        : m_importPermutations.remove(0);
-
-                    calculatePackageSpaces(
-                        module, candidateMap, modulePkgMap,
-                        new HashMap(), new HashSet());
-
-                    try
+                    // Try to populate optional fragments.
+                    for (Module fragment : fragments)
                     {
-                        checkPackageSpaceConsistency(
-                            true, module, candidateMap, modulePkgMap, new HashMap());
+                        try
+                        {
+                            populateCandidates(state, fragment, allCandidates, resultCache);
+                        }
+                        catch (ResolveException ex)
+                        {
+                            // Ignore, since fragments are optional.
+                         }
                     }
-                    catch (ResolveException ex)
+
+                    // Merge any fragments into hosts.
+                    allCandidates.mergeFragments();
+
+                    // Record the initial candidate permutation.
+                     m_usesPermutations.add(allCandidates);
+
+                    ResolveException rethrow = null;
+
+                    // If the requested module is a fragment, then
+                    // ultimately we will verify the host.
+                    Requirement hostReq = getHostRequirement(module);
+                    Module target = module;
+
+                    do
                     {
-                        rethrow = ex;
-                    }
-                }
-                while ((rethrow != null)
-                    && ((m_usesPermutations.size() > 0)
-                        || (m_importPermutations.size() > 0)));
+                        rethrow = null;
 
-                if (rethrow != null)
-                {
-                    throw rethrow;
-                }
+                        modulePkgMap.clear();
+                        m_packageSourcesCache.clear();
 
+                        allCandidates = (m_usesPermutations.size() > 0)
+                            ? m_usesPermutations.remove(0)
+                            : m_importPermutations.remove(0);
+//allCandidates.dump();
+
+                        // For a dynamic import, the instigating module
+                        // will never be a fragment since fragments never
+                        // execute code, so we don't need to check for
+                        // this case like we do for a normal resolve.
+
+                        calculatePackageSpaces(
+                            allCandidates.getWrappedHost(target), allCandidates, modulePkgMap,
+                            new HashMap(), new HashSet());
+//System.out.println("+++ PACKAGE SPACES START +++");
 //dumpModulePkgMap(modulePkgMap);
-                wireMap = populateDynamicWireMap(
-                    module, pkgName, modulePkgMap, wireMap, candidateMap);
+//System.out.println("+++ PACKAGE SPACES END +++");
 
-                return wireMap;
+                        try
+                        {
+                            checkPackageSpaceConsistency(
+                                false, allCandidates.getWrappedHost(target),
+                                allCandidates, modulePkgMap, new HashMap());
+                        }
+                        catch (ResolveException ex)
+                        {
+                            rethrow = ex;
+                        }
+                    }
+                    while ((rethrow != null)
+                        && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
+
+                    // If there is a resolve exception, then determine if an
+                    // optionally resolved module is to blame (typically a fragment).
+                    // If so, then remove the optionally resolved module and try
+                    // again; otherwise, rethrow the resolve exception.
+                    if (rethrow != null)
+                    {
+                        Module faultyModule = getActualModule(rethrow.getModule());
+                        if (rethrow.getRequirement() instanceof WrappedRequirement)
+                        {
+                            faultyModule =
+                                ((WrappedRequirement) rethrow.getRequirement())
+                                    .getWrappedRequirement().getModule();
+                        }
+                        if (fragments.remove(faultyModule))
+                        {
+                            retryFragments = true;
+                        }
+                        else
+                        {
+                            throw rethrow;
+                        }
+                    }
+                    // If there is no exception to rethrow, then this was a clean
+                    // resolve, so populate the wire map.
+                    else
+                    {
+                        wireMap = populateDynamicWireMap(
+                            module, pkgName, modulePkgMap, wireMap, allCandidates);
+                        return wireMap;
+                    }
+                }
+                finally
+                {
+                    // Always clear the state.
+                    m_usesPermutations.clear();
+                    m_importPermutations.clear();
+                }
             }
-            finally
-            {
-                // Always clear the state.
-                m_usesPermutations.clear();
-                m_importPermutations.clear();
-            }
+            while (retryFragments);
         }
 
         return null;
     }
 
-    private static Map<Requirement, Set<Capability>> getDynamicImportCandidates(
+    private static Capability getHostCapability(Module m)
+    {
+        for (Capability c : m.getCapabilities())
+        {
+            if (c.getNamespace().equals(Capability.HOST_NAMESPACE))
+            {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    private static Requirement getHostRequirement(Module m)
+    {
+        for (Requirement r : m.getRequirements())
+        {
+            if (r.getNamespace().equals(Capability.HOST_NAMESPACE))
+            {
+                return r;
+            }
+        }
+        return null;
+    }
+
+    private static Candidates getDynamicImportCandidates(
         ResolverState state, Module module, String pkgName)
     {
         // Unresolved modules cannot dynamically import, nor can the default
@@ -250,7 +398,7 @@
         attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
         Requirement req = new RequirementImpl(
             module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<Capability> candidates = state.getCandidates(module, req, false);
+        SortedSet<Capability> candidates = state.getCandidates(module, req, false);
 
         // First find a dynamic requirement that matches the capabilities.
         Requirement dynReq = null;
@@ -289,9 +437,9 @@
 
         if (candidates.size() > 0)
         {
-            Map<Requirement, Set<Capability>> candidateMap = new HashMap();
-            candidateMap.put(dynReq, candidates);
-            return candidateMap;
+            Candidates allCandidates = new Candidates(module);
+            allCandidates.add(dynReq, candidates);
+            return allCandidates;
         }
 
         return null;
@@ -299,8 +447,7 @@
 
 // TODO: FELIX3 - Modify to not be recursive.
     private void populateCandidates(
-        ResolverState state, Module module,
-        Map<Requirement, Set<Capability>> candidateMap,
+        ResolverState state, Module module, Candidates allCandidates,
         Map<Module, Object> resultCache)
     {
         // Determine if we've already calculated this module's candidates.
@@ -323,7 +470,7 @@
 
         // Keeps track of the candidates we've already calculated for the
         // current module's requirements.
-        Map<Requirement, Set<Capability>> localCandidateMap = null;
+        Map<Requirement, SortedSet<Capability>> localCandidateMap = null;
 
         // Keeps track of the current module's requirements for which we
         // haven't yet found candidates.
@@ -390,7 +537,7 @@
 
             // Get satisfying candidates and populate their candidates if necessary.
             ResolveException rethrow = null;
-            Set<Capability> candidates = state.getCandidates(module, req, true);
+            SortedSet<Capability> candidates = state.getCandidates(module, req, true);
             for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
             {
                 Capability candCap = itCandCap.next();
@@ -410,7 +557,7 @@
                     try
                     {
                         populateCandidates(state, candCap.getModule(),
-                            candidateMap, resultCache);
+                            allCandidates, resultCache);
                     }
                     catch (ResolveException ex)
                     {
@@ -438,11 +585,6 @@
                 }
                 rethrow = new ResolveException(msg, module, req);
                 resultCache.put(module, rethrow);
-                m_logger.log(
-                    module.getBundle(),
-                    Logger.LOG_DEBUG,
-                    "No viable candidates",
-                    rethrow);
                 throw rethrow;
             }
             // If we actually have candidates for the requirement, then
@@ -467,22 +609,23 @@
             // Merge local candidate map into global candidate map.
             if (localCandidateMap.size() > 0)
             {
-                candidateMap.putAll(localCandidateMap);
+                allCandidates.add(localCandidateMap);
             }
         }
     }
 
     private void populateDynamicCandidates(
-        ResolverState state, Module module,
-        Map<Requirement, Set<Capability>> candidateMap)
+        ResolverState state, Module module, Candidates allCandidates,
+        Map<Module, Object> resultCache)
     {
         // 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.
         ResolveException rethrow = null;
-        Entry<Requirement, Set<Capability>> entry = candidateMap.entrySet().iterator().next();
+        Entry<Requirement, SortedSet<Capability>> entry =
+            allCandidates.getCandidateMap().entrySet().iterator().next();
         Requirement dynReq = entry.getKey();
-        Set<Capability> candidates = entry.getValue();
+        SortedSet<Capability> candidates = entry.getValue();
         for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
         {
             Capability candCap = itCandCap.next();
@@ -491,7 +634,7 @@
                 try
                 {
                     populateCandidates(state, candCap.getModule(),
-                        candidateMap, new HashMap<Module, Object>());
+                        allCandidates, resultCache);
                 }
                 catch (ResolveException ex)
                 {
@@ -506,7 +649,6 @@
 
         if (candidates.isEmpty())
         {
-            candidateMap.remove(dynReq);
             if (rethrow == null)
             {
                 rethrow = new ResolveException("Dynamic import failed.", module, dynReq);
@@ -517,7 +659,7 @@
 
     private void calculatePackageSpaces(
         Module module,
-        Map<Requirement, Set<Capability>> candidateMap,
+        Candidates allCandidates,
         Map<Module, Packages> modulePkgMap,
         Map<Capability, List<Module>> usesCycleMap,
         Set<Module> cycle)
@@ -548,7 +690,7 @@
             for (Requirement req : module.getDynamicRequirements())
             {
                 // Get the candidates for the current requirement.
-                Set<Capability> candCaps = candidateMap.get(req);
+                SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
@@ -569,7 +711,7 @@
             for (Requirement req : module.getRequirements())
             {
                 // Get the candidates for the current requirement.
-                Set<Capability> candCaps = candidateMap.get(req);
+                SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
@@ -583,7 +725,7 @@
         }
 
         // First, add all exported packages to the target module's package space.
-        calculateExportedPackages(module, candidateMap, modulePkgMap);
+        calculateExportedPackages(module, allCandidates, modulePkgMap);
         Packages modulePkgs = modulePkgMap.get(module);
 
         // Second, add all imported packages to the target module's package space.
@@ -591,15 +733,15 @@
         {
             Requirement req = reqs.get(i);
             Capability cap = caps.get(i);
-            calculateExportedPackages(cap.getModule(), candidateMap, modulePkgMap);
-            mergeCandidatePackages(module, req, cap, modulePkgMap, candidateMap);
+            calculateExportedPackages(cap.getModule(), allCandidates, modulePkgMap);
+            mergeCandidatePackages(module, req, cap, modulePkgMap, allCandidates);
         }
 
         // Third, have all candidates to calculate their package spaces.
         for (int i = 0; i < caps.size(); i++)
         {
             calculatePackageSpaces(
-                caps.get(i).getModule(), candidateMap, modulePkgMap,
+                caps.get(i).getModule(), allCandidates, modulePkgMap,
                 usesCycleMap, cycle);
         }
 
@@ -630,7 +772,7 @@
                             blame.m_cap,
                             blameReqs,
                             modulePkgMap,
-                            candidateMap,
+                            allCandidates,
                             usesCycleMap);
                     }
                 }
@@ -648,7 +790,7 @@
                         blame.m_cap,
                         blameReqs,
                         modulePkgMap,
-                        candidateMap,
+                        allCandidates,
                         usesCycleMap);
                 }
             }
@@ -657,7 +799,8 @@
 
     private void mergeCandidatePackages(
         Module current, Requirement currentReq, Capability candCap,
-        Map<Module, Packages> modulePkgMap, Map<Requirement, Set<Capability>> candidateMap)
+        Map<Module, Packages> modulePkgMap,
+        Candidates allCandidates)
     {
         if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
         {
@@ -668,7 +811,7 @@
         {
 // TODO: FELIX3 - THIS NEXT LINE IS A HACK. IMPROVE HOW/WHEN WE CALCULATE EXPORTS.
             calculateExportedPackages(
-                candCap.getModule(), candidateMap, modulePkgMap);
+                candCap.getModule(), allCandidates, modulePkgMap);
 
             // Get the candidate's package space to determine which packages
             // will be visible to the current module.
@@ -694,14 +837,14 @@
                 {
                     Directive dir = req.getDirective(Constants.VISIBILITY_DIRECTIVE);
                     if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT)
-                        && (candidateMap.get(req) != null))
+                        && (allCandidates.getCandidates(req) != null))
                     {
                         mergeCandidatePackages(
                             current,
                             currentReq,
-                            candidateMap.get(req).iterator().next(),
+                            allCandidates.getCandidates(req).iterator().next(),
                             modulePkgMap,
-                            candidateMap);
+                            allCandidates);
                     }
                 }
             }
@@ -760,8 +903,9 @@
 
     private void mergeUses(
         Module current, Packages currentPkgs,
-        Capability mergeCap, List<Requirement> blameReqs, Map<Module, Packages> modulePkgMap,
-        Map<Requirement, Set<Capability>> candidateMap,
+        Capability mergeCap, List<Requirement> blameReqs,
+        Map<Module, Packages> modulePkgMap,
+        Candidates allCandidates,
         Map<Capability, List<Module>> cycleMap)
     {
         if (!mergeCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
@@ -821,14 +965,14 @@
                         List<Requirement> blameReqs2 = new ArrayList(blameReqs);
                         blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
                         usedCaps.add(new Blame(blame.m_cap, blameReqs2));
-                            mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
-                            modulePkgMap, candidateMap, cycleMap);
+                        mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
+                            modulePkgMap, allCandidates, cycleMap);
                     }
                     else
                     {
                         usedCaps.add(new Blame(blame.m_cap, blameReqs));
                         mergeUses(current, currentPkgs, blame.m_cap, blameReqs,
-                            modulePkgMap, candidateMap, cycleMap);
+                            modulePkgMap, allCandidates, cycleMap);
                     }
                 }
             }
@@ -836,8 +980,9 @@
     }
 
     private void checkPackageSpaceConsistency(
-        boolean isDynamicImport, Module module,
-        Map<Requirement, Set<Capability>> candidateMap,
+        boolean isDynamicImport,
+        Module module,
+        Candidates allCandidates,
         Map<Module, Packages> modulePkgMap,
         Map<Module, Object> resultCache)
     {
@@ -853,7 +998,7 @@
         Packages pkgs = modulePkgMap.get(module);
 
         ResolveException rethrow = null;
-        Map<Requirement, Set<Capability>> permutation = null;
+        Candidates permutation = null;
         Set<Requirement> mutated = null;
 
         // Check for conflicting imports from fragments.
@@ -871,9 +1016,9 @@
                     else if (!sourceBlame.m_cap.getModule().equals(blame.m_cap.getModule()))
                     {
                         // Try to permutate the conflicting requirement.
-                        permutate(candidateMap, blame.m_reqs.get(0), m_importPermutations);
+                        permutate(allCandidates, blame.m_reqs.get(0), m_importPermutations);
                         // Try to permutate the source requirement.
-                        permutate(candidateMap, sourceBlame.m_reqs.get(0), m_importPermutations);
+                        permutate(allCandidates, sourceBlame.m_reqs.get(0), m_importPermutations);
                         // Report conflict.
                         ResolveException ex = new ResolveException(
                             "Unable to resolve module "
@@ -920,7 +1065,7 @@
                     // that conflict with existing selected candidates.
                     permutation = (permutation != null)
                         ? permutation
-                        : copyCandidateMap(candidateMap);
+                        : allCandidates.copy();
                     rethrow = (rethrow != null)
                         ? rethrow
                         : new ResolveException(
@@ -956,7 +1101,7 @@
                         // See if we can permutate the candidates for blamed
                         // requirement; there may be no candidates if the module
                         // associated with the requirement is already resolved.
-                        Set<Capability> candidates = permutation.get(req);
+                        SortedSet<Capability> candidates = permutation.getCandidates(req);
                         if ((candidates != null) && (candidates.size() > 1))
                         {
                             mutated.add(req);
@@ -985,7 +1130,7 @@
             }
         }
 
-        // Check if there are any conflicts with imported packages.
+        // Check if there are any uses conflicts with imported packages.
         for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
         {
             for (Blame importBlame : entry.getValue())
@@ -1003,7 +1148,7 @@
                         // that conflict with existing selected candidates.
                         permutation = (permutation != null)
                             ? permutation
-                            : copyCandidateMap(candidateMap);
+                            : allCandidates.copy();
                         rethrow = (rethrow != null)
                             ? rethrow
                             : new ResolveException(
@@ -1044,7 +1189,7 @@
                             // See if we can permutate the candidates for blamed
                             // requirement; there may be no candidates if the module
                             // associated with the requirement is already resolved.
-                            Set<Capability> candidates = permutation.get(req);
+                            SortedSet<Capability> candidates = permutation.getCandidates(req);
                             if ((candidates != null) && (candidates.size() > 1))
                             {
                                 mutated.add(req);
@@ -1082,7 +1227,7 @@
                         // with existing import decisions, we may end up trying
                         // to permutate the same import a lot of times, so we should
                         // try to check if that the case and only permutate it once.
-                        permutateIfNeeded(candidateMap, req, m_importPermutations);
+                        permutateIfNeeded(allCandidates, req, m_importPermutations);
                     }
 
                     m_logger.log(
@@ -1111,8 +1256,8 @@
                     try
                     {
                         checkPackageSpaceConsistency(
-                            false, importBlame.m_cap.getModule(), candidateMap,
-                            modulePkgMap, resultCache);
+                            false, importBlame.m_cap.getModule(),
+                            allCandidates, modulePkgMap, resultCache);
                     }
                     catch (ResolveException ex)
                     {
@@ -1123,7 +1268,7 @@
                         if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
                         {
                             Requirement req = importBlame.m_reqs.get(0);
-                            permutate(candidateMap, req, m_importPermutations);
+                            permutate(allCandidates, req, m_importPermutations);
                         }
                         throw ex;
                     }
@@ -1133,14 +1278,13 @@
     }
 
     private static void permutate(
-        Map<Requirement, Set<Capability>> candidateMap, Requirement req,
-        List<Map<Requirement, Set<Capability>>> permutations)
+        Candidates allCandidates, Requirement req, List<Candidates> permutations)
     {
-        Set<Capability> candidates = candidateMap.get(req);
+        SortedSet<Capability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
-            Map<Requirement, Set<Capability>> perm = copyCandidateMap(candidateMap);
-            candidates = perm.get(req);
+            Candidates perm = allCandidates.copy();
+            candidates = perm.getCandidates(req);
             Iterator it = candidates.iterator();
             it.next();
             it.remove();
@@ -1149,10 +1293,9 @@
     }
 
     private static void permutateIfNeeded(
-        Map<Requirement, Set<Capability>> candidateMap, Requirement req,
-        List<Map<Requirement, Set<Capability>>> permutations)
+        Candidates allCandidates, Requirement req, List<Candidates> permutations)
     {
-        Set<Capability> candidates = candidateMap.get(req);
+        SortedSet<Capability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             // Check existing permutations to make sure we haven't
@@ -1162,9 +1305,9 @@
             // initial candidate for the requirement in question,
             // then it has already been permutated.
             boolean permutated = false;
-            for (Map<Requirement, Set<Capability>> existingPerm : permutations)
+            for (Candidates existingPerm : permutations)
             {
-                Set<Capability> existingPermCands = existingPerm.get(req);
+                Set<Capability> existingPermCands = existingPerm.getCandidates(req);
                 if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
                 {
                     permutated = true;
@@ -1174,14 +1317,14 @@
             // import, do so now.
             if (!permutated)
             {
-                permutate(candidateMap, req, permutations);
+                permutate(allCandidates, req, permutations);
             }
         }
     }
 
     private static void calculateExportedPackages(
         Module module,
-        Map<Requirement, Set<Capability>> candidateMap,
+        Candidates allCandidates,
         Map<Module, Packages> modulePkgMap)
     {
         Packages packages = modulePkgMap.get(module);
@@ -1225,7 +1368,7 @@
             {
                 if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
                 {
-                    Set<Capability> cands = candidateMap.get(req);
+                    Set<Capability> cands = allCandidates.getCandidates(req);
                     if ((cands != null) && !cands.isEmpty())
                     {
                         String pkgName = (String) cands.iterator().next()
@@ -1331,60 +1474,77 @@
         return sources;
     }
 
-    private static Map<Requirement, Set<Capability>> copyCandidateMap(
-        Map<Requirement, Set<Capability>> candidateMap)
+    private static Module getActualModule(Module m)
     {
-        Map<Requirement, Set<Capability>> copy =
-            new HashMap<Requirement, Set<Capability>>();
-        for (Entry<Requirement, Set<Capability>> entry : candidateMap.entrySet())
+        if (m instanceof WrappedModule)
         {
-            Set<Capability> candidates = new TreeSet(new CandidateComparator());
-            candidates.addAll(entry.getValue());
-            copy.put(entry.getKey(), candidates);
+            return ((WrappedModule) m).getWrappedModule();
         }
-        return copy;
+        return m;
+    }
+
+    private static Capability getActualCapability(Capability c)
+    {
+        if (c instanceof WrappedCapability)
+        {
+            return ((WrappedCapability) c).getWrappedCapability();
+        }
+        return c;
+    }
+
+    private static Requirement getActualRequirement(Requirement r)
+    {
+        if (r instanceof WrappedRequirement)
+        {
+            return ((WrappedRequirement) r).getWrappedRequirement();
+        }
+        return r;
     }
 
     private static Map<Module, List<Wire>> populateWireMap(
         Module module, Map<Module, Packages> modulePkgMap,
-        Map<Module, List<Wire>> wireMap, Map<Requirement, Set<Capability>> candidateMap)
+        Map<Module, List<Wire>> wireMap,
+        Candidates allCandidates)
     {
-        if (!module.isResolved() && !wireMap.containsKey(module))
+        Module unwrappedModule = getActualModule(module);
+        if (!unwrappedModule.isResolved() && !wireMap.containsKey(unwrappedModule))
         {
-            wireMap.put(module, (List<Wire>) Collections.EMPTY_LIST);
+            wireMap.put(unwrappedModule, (List<Wire>) Collections.EMPTY_LIST);
 
             List<Wire> packageWires = new ArrayList<Wire>();
             List<Wire> moduleWires = new ArrayList<Wire>();
 
             for (Requirement req : module.getRequirements())
             {
-                Set<Capability> cands = candidateMap.get(req);
+                SortedSet<Capability> cands = allCandidates.getCandidates(req);
                 if ((cands != null) && (cands.size() > 0))
                 {
                     Capability cand = cands.iterator().next();
                     if (!cand.getModule().isResolved())
                     {
                         populateWireMap(cand.getModule(),
-                            modulePkgMap, wireMap, candidateMap);
+                            modulePkgMap, wireMap, allCandidates);
                     }
                     // 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));
+                            new WireImpl(
+                                unwrappedModule,
+                                getActualRequirement(req),
+                                getActualModule(cand.getModule()),
+                                getActualCapability(cand)));
                     }
                     else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
                     {
                         Packages candPkgs = modulePkgMap.get(cand.getModule());
                         moduleWires.add(
-                            new WireModuleImpl(module,
-                                req,
-                                cand.getModule(),
-                                cand,
+                            new WireModuleImpl(
+                                unwrappedModule,
+                                getActualRequirement(req),
+                                getActualModule(cand.getModule()),
+                                getActualCapability(cand),
                                 candPkgs.getExportedAndReexportedPackages()));
                     }
                 }
@@ -1392,7 +1552,28 @@
 
             // Combine wires with module wires last.
             packageWires.addAll(moduleWires);
-            wireMap.put(module, packageWires);
+            wireMap.put(unwrappedModule, packageWires);
+
+            // Add host wire for any fragments.
+            if (module instanceof WrappedModule)
+            {
+                List<Module> fragments = ((WrappedModule) module).getFragments();
+                for (Module fragment : fragments)
+                {
+                    List<Wire> hostWires = wireMap.get(fragment);
+                    if (hostWires == null)
+                    {
+                        hostWires = new ArrayList<Wire>();
+                        wireMap.put(fragment, hostWires);
+                    }
+                    hostWires.add(
+                        new WireHostImpl(
+                            getActualModule(fragment),
+                            getHostRequirement(fragment),
+                            unwrappedModule,
+                            getHostCapability(unwrappedModule)));
+                }
+            }
         }
 
         return wireMap;
@@ -1400,7 +1581,7 @@
 
     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)
+        Map<Module, List<Wire>> wireMap, Candidates allCandidates)
     {
         wireMap.put(module, (List<Wire>) Collections.EMPTY_LIST);
 
@@ -1419,7 +1600,7 @@
                     if (!blame.m_cap.getModule().isResolved())
                     {
                         populateWireMap(blame.m_cap.getModule(), modulePkgMap, wireMap,
-                            candidateMap);
+                            allCandidates);
                     }
 
                     List<Attribute> attrs = new ArrayList();
@@ -1446,40 +1627,6 @@
         return wireMap;
     }
 
-    private static void dumpCandidateMap(Map<Requirement, Set<Capability>> candidateMap)
-    {
-        // Create set of all modules from requirements.
-        Set<Module> modules = new HashSet();
-        for (Entry<Requirement, Set<Capability>> entry : candidateMap.entrySet())
-        {
-            modules.add(entry.getKey().getModule());
-        }
-        // Now dump the modules.
-        System.out.println("=== BEGIN CANDIDATE MAP ===");
-        for (Module module : modules)
-        {
-            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+++");
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireHostImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireHostImpl.java
new file mode 100644
index 0000000..ca188a2
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireHostImpl.java
@@ -0,0 +1,87 @@
+/*
+ *  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;
+
+class WireHostImpl implements Wire
+{
+    private final Module m_importer;
+    private final Requirement m_req;
+    private final Module m_exporter;
+    private final Capability m_cap;
+
+    public WireHostImpl(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_importer
+            + " -> hosted by -> "
+            + m_exporter;
+    }
+
+    public boolean hasPackage(String pkgName)
+    {
+        return false;
+    }
+
+    public Class getClass(String name) throws ClassNotFoundException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public URL getResource(String name) throws ResourceNotFoundException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Enumeration getResources(String name) throws ResourceNotFoundException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
\ No newline at end of file
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
index 7e3076d..f2476d1 100755
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
@@ -25,6 +25,7 @@
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
 
+// TODO: FRAGMENT-RESOLVER - This should probably be package private.
 public class WireImpl implements Wire
 {
     private final Module m_importer;
@@ -62,7 +63,10 @@
 
     public String toString()
     {
-        return m_req + " -> " + "[" + m_exporter + "]";
+        return "[" + m_importer + "] "
+            + m_req.getNamespace() + "; "
+            + m_req.getFilter() + " -> "
+            + "[" + m_exporter + "]";
     }
 
     /* (non-Javadoc)
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
index 124c45c..00ef370 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
@@ -25,6 +25,7 @@
 import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.Util;
 
+// TODO: FRAGMENT-RESOLVER - This should probably be package private.
 public class WireModuleImpl implements Wire
 {
     private final Module m_importer;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
new file mode 100644
index 0000000..29f5d00
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
@@ -0,0 +1,90 @@
+/*
+ * 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 org.apache.felix.framework.capabilityset.Attribute;
+import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.capabilityset.Directive;
+
+class WrappedCapability implements Capability
+{
+    private final Module m_module;
+    private final Capability m_cap;
+
+    public WrappedCapability(Module module, Capability cap)
+    {
+        m_module = module;
+        m_cap = cap;
+    }
+
+    public Capability getWrappedCapability()
+    {
+        return m_cap;
+    }
+
+    public Module getModule()
+    {
+        return m_module;
+    }
+
+    public String getNamespace()
+    {
+        return m_cap.getNamespace();
+    }
+
+    public Directive getDirective(String name)
+    {
+        return m_cap.getDirective(name);
+    }
+
+    public List<Directive> getDirectives()
+    {
+        return m_cap.getDirectives();
+    }
+
+    public Attribute getAttribute(String name)
+    {
+        return m_cap.getAttribute(name);
+    }
+
+    public List<Attribute> getAttributes()
+    {
+        return m_cap.getAttributes();
+    }
+
+    public List<String> getUses()
+    {
+        return m_cap.getUses();
+    }
+
+    public String toString()
+    {
+        if (m_module == null)
+        {
+            return getAttributes().toString();
+        }
+        if (getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        {
+            return "[" + m_module + "] "
+                + getNamespace() + "; " + getAttribute(Capability.PACKAGE_ATTR);
+        }
+        return "[" + m_module + "] " + getNamespace() + "; " + getAttributes();
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedModule.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedModule.java
new file mode 100644
index 0000000..133ebc3
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedModule.java
@@ -0,0 +1,241 @@
+/*
+ * 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.ArrayList;
+import java.util.Collections;
+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;
+
+class WrappedModule implements Module
+{
+    private final String m_id;
+    private final Module m_module;
+    private final List<Module> m_fragments;
+    private List<Capability> m_cachedCapabilities = null;
+    private List<Requirement> m_cachedRequirements = null;
+
+    public WrappedModule(Module module, List<Module> fragments)
+    {
+        m_id = module.getId() + " [" + super.hashCode() + "]";
+        m_module = module;
+        m_fragments = fragments;
+    }
+
+    public Module getWrappedModule()
+    {
+        return m_module;
+    }
+
+    public List<Module> getFragments()
+    {
+        return m_fragments;
+    }
+
+    public String getId()
+    {
+        return m_id;
+    }
+
+    public List<Capability> getCapabilities()
+    {
+        if (m_cachedCapabilities == null)
+        {
+            List<Capability> capList = new ArrayList<Capability>();
+
+            // Wrap host capabilities.
+            List<Capability> caps = m_module.getCapabilities();
+            for (int capIdx = 0;
+                (caps != null) && (capIdx < caps.size());
+                capIdx++)
+            {
+                capList.add(
+                    new WrappedCapability(this, caps.get(capIdx)));
+            }
+
+            // Wrap fragment capabilities.
+            for (int fragIdx = 0;
+                (m_fragments != null) && (fragIdx < m_fragments.size());
+                fragIdx++)
+            {
+                caps = m_fragments.get(fragIdx).getCapabilities();
+                for (int capIdx = 0;
+                    (caps != null) && (capIdx < caps.size());
+                    capIdx++)
+                {
+                    if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    {
+                        capList.add(
+                            new WrappedCapability(this, caps.get(capIdx)));
+                    }
+                }
+            }
+            m_cachedCapabilities = Collections.unmodifiableList(capList);
+        }
+        return m_cachedCapabilities;
+    }
+
+    public List<Requirement> getRequirements()
+    {
+        if (m_cachedRequirements == null)
+        {
+            List<Requirement> reqList = new ArrayList<Requirement>();
+
+            // Wrap host requirements.
+            List<Requirement> reqs = m_module.getRequirements();
+            for (int reqIdx = 0;
+                (reqs != null) && (reqIdx < reqs.size());
+                reqIdx++)
+            {
+                reqList.add(
+                    new WrappedRequirement(this, reqs.get(reqIdx)));
+            }
+
+            // Wrap fragment requirements.
+            for (int fragIdx = 0;
+                (m_fragments != null) && (fragIdx < m_fragments.size());
+                fragIdx++)
+            {
+                reqs = m_fragments.get(fragIdx).getRequirements();
+                for (int reqIdx = 0;
+                    (reqs != null) && (reqIdx < reqs.size());
+                    reqIdx++)
+                {
+                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                        || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
+                    {
+                        reqList.add(
+                            new WrappedRequirement(this, reqs.get(reqIdx)));
+                    }
+                }
+            }
+            m_cachedRequirements = Collections.unmodifiableList(reqList);
+        }
+        return m_cachedRequirements;
+    }
+
+    public Map getHeaders()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean isExtension()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public String getSymbolicName()
+    {
+        return m_module.getSymbolicName();
+    }
+
+    public Version getVersion()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<Requirement> getDynamicRequirements()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<R4Library> getNativeLibraries()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public int getDeclaredActivationPolicy()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Bundle getBundle()
+    {
+        return m_module.getBundle();
+    }
+
+    public List<Wire> getWires()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean isResolved()
+    {
+        return false;
+    }
+
+    public Object getSecurityContext()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean isRemovalPending()
+    {
+        return m_module.isRemovalPending();
+    }
+
+    public Content getContent()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Class getClassByDelegation(String name) throws ClassNotFoundException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public URL getResourceByDelegation(String name)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Enumeration getResourcesByDelegation(String name)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public URL getEntry(String name)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean hasInputStream(int index, String urlPath) throws IOException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public InputStream getInputStream(int index, String urlPath) throws IOException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public URL getLocalURL(int index, String urlPath)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
new file mode 100644
index 0000000..a188ce1
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
@@ -0,0 +1,76 @@
+/*
+ * 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 org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
+
+class WrappedRequirement implements Requirement
+{
+    private final Module m_module;
+    private final Requirement m_req;
+
+    public WrappedRequirement(Module module, Requirement req)
+    {
+        m_module = module;
+        m_req = req;
+    }
+
+    public Requirement getWrappedRequirement()
+    {
+        return m_req;
+    }
+
+    public Module getModule()
+    {
+        return m_module;
+    }
+
+    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();
+    }
+
+    public String toString()
+    {
+        return "[" + m_module + "] " + getNamespace() + "; " + getFilter().toString();
+    }
+}
\ No newline at end of file
