diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
index fbd016b..8ac2d61 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -29,7 +29,6 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.cache.Content;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.SecureAction;
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index ea0ca0a..1326b4a 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -26,7 +26,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -38,11 +37,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
-import java.util.SortedSet;
 import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.jar.Manifest;
-import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.cache.JarContent;
 import org.apache.felix.framework.cache.Content;
 import org.apache.felix.framework.resolver.HostedCapability;
@@ -51,7 +46,6 @@
 import org.apache.felix.framework.resolver.ResourceNotFoundException;
 import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.FelixConstants;
-import org.apache.felix.framework.util.SecureAction;
 import org.apache.felix.framework.util.SecurityManagerEx;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
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 5c63347..9561f7f 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -37,9 +37,7 @@
 import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Set;
-import org.apache.felix.framework.Felix.StatefulResolver;
 
-import org.apache.felix.framework.resolver.ResolverWire;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
@@ -56,7 +54,6 @@
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 
 /**
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 b362f2a..105e6cb 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -371,11 +371,7 @@
         m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
 
         // Create a resolver and its state.
-        m_resolver = new StatefulResolver(
-            new ResolverImpl(m_logger),
-            new ResolverStateImpl(
-                m_logger,
-                (String) m_configMap.get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT)));
+        m_resolver = new StatefulResolver(this);
 
         // Create the extension manager, which we will use as the
         // revision for the system bundle.
@@ -423,6 +419,11 @@
         return m_resolver;
     }
 
+    BundleRevisionDependencies getDependencies()
+    {
+        return m_dependencies;
+    }
+
     URLStreamHandler getBundleStreamHandler()
     {
         return m_bundleStreamHandler;
@@ -4099,7 +4100,7 @@
      * @param type The type of bundle event to fire.
      * @param bundle The bundle associated with the event.
     **/
-    private void fireBundleEvent(int type, Bundle bundle)
+    void fireBundleEvent(int type, Bundle bundle)
     {
         m_dispatcher.fireBundleEvent(new BundleEvent(type, bundle));
     }
@@ -4317,536 +4318,6 @@
     // Miscellaneous inner classes.
     //
 
-    class StatefulResolver
-    {
-        private final Resolver m_resolver;
-        private final ResolverStateImpl m_resolverState;
-
-        StatefulResolver(Resolver resolver, ResolverStateImpl resolverState)
-        {
-            m_resolver = resolver;
-            m_resolverState = resolverState;
-        }
-
-        void addRevision(BundleRevision br)
-        {
-            m_resolverState.addRevision(br);
-        }
-
-        void removeRevision(BundleRevision br)
-        {
-            m_resolverState.removeRevision(br);
-        }
-
-        Set<BundleCapability> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
-        {
-            return m_resolverState.getCandidates(req, obeyMandatory);
-        }
-
-        void resolve(BundleRevision rootRevision) 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
-            // a lock just to check if the revision is resolved, which itself
-            // is a safe read. If the revision isn't resolved, we end up double
-            // check the resolved status later.
-// TODO: OSGi R4.3 - This locking strategy here depends on how we ultimately
-//       implement getWiring(), which may change.
-            if (rootRevision.getWiring() == null)
-            {
-                // Acquire global lock.
-                boolean locked = acquireGlobalLock();
-                if (!locked)
-                {
-                    throw new ResolveException(
-                        "Unable to acquire global lock for resolve.", rootRevision, null);
-                }
-
-                Map<BundleRevision, List<ResolverWire>> wireMap = null;
-                try
-                {
-                    BundleImpl bundle = (BundleImpl) rootRevision.getBundle();
-
-                    // Extensions are resolved differently.
-                    if (bundle.isExtension())
-                    {
-                        return;
-                    }
-
-                    // Resolve the revision.
-                    wireMap = m_resolver.resolve(
-                        m_resolverState, rootRevision, m_resolverState.getFragments());
-
-                    // Mark all revisions as resolved.
-                    markResolvedRevisions(wireMap);
-                }
-                finally
-                {
-                    // Always release the global lock.
-                    releaseGlobalLock();
-                }
-
-                fireResolvedEvents(wireMap);
-            }
-        }
-
-        BundleRevision resolve(BundleRevision revision, String pkgName)
-            throws ResolveException
-        {
-            BundleRevision provider = null;
-
-            // We cannot dynamically import if the revision is not already resolved
-            // or if it is not allowed, so check that first. Note: We check if the
-            // dynamic import is allowed without holding any locks, but this is
-            // okay since the resolver will double check later after we have
-            // acquired the global lock below.
-            if ((revision.getWiring() != null) && isAllowedDynamicImport(revision, pkgName))
-            {
-                // Acquire global lock.
-                boolean locked = acquireGlobalLock();
-                if (!locked)
-                {
-                    throw new ResolveException(
-                        "Unable to acquire global lock for resolve.", revision, null);
-                }
-
-                Map<BundleRevision, List<ResolverWire>> wireMap = null;
-                try
-                {
-                    // Double check to make sure that someone hasn't beaten us to
-                    // dynamically importing the package, which can happen if two
-                    // threads are racing to do so. If we have an existing wire,
-                    // then just return it instead.
-                    provider = ((BundleWiringImpl) revision.getWiring())
-                        .getImportedPackageSource(pkgName);
-                    if (provider == null)
-                    {
-                        wireMap = m_resolver.resolve(
-                            m_resolverState, revision, pkgName,
-                            m_resolverState.getFragments());
-
-                        if ((wireMap != null) && wireMap.containsKey(revision))
-                        {
-                            List<ResolverWire> dynamicWires = wireMap.remove(revision);
-                            ResolverWire dynamicWire = dynamicWires.get(0);
-
-                            // Mark all revisions as resolved.
-                            markResolvedRevisions(wireMap);
-
-                            // Dynamically add new wire to importing revision.
-                            if (dynamicWire != null)
-                            {
-                                m_dependencies.addDependent(
-                                    dynamicWire.getProvider(),
-                                    dynamicWire.getCapability(),
-                                    revision);
-
-                                ((BundleWiringImpl) revision.getWiring())
-                                    .addDynamicWire(
-                                        new BundleWireImpl(
-                                            dynamicWire.getRequirer(),
-                                            dynamicWire.getRequirement(),
-                                            dynamicWire.getProvider(),
-                                            dynamicWire.getCapability()));
-
-                                m_logger.log(
-                                    Logger.LOG_DEBUG,
-                                    "DYNAMIC WIRE: " + dynamicWire);
-
-                                provider = ((BundleWiringImpl) revision.getWiring())
-                                    .getImportedPackageSource(pkgName);
-                            }
-                        }
-                    }
-                }
-                finally
-                {
-                    // Always release the global lock.
-                    releaseGlobalLock();
-                }
-
-                fireResolvedEvents(wireMap);
-            }
-
-            return provider;
-        }
-
-        // This method duplicates a lot of logic from:
-        // ResolverImpl.getDynamicImportCandidates()
-        boolean isAllowedDynamicImport(BundleRevision revision, String pkgName)
-        {
-            // Unresolved revisions cannot dynamically import, nor can the default
-            // package be dynamically imported.
-            if ((revision.getWiring() == null) || pkgName.length() == 0)
-            {
-                return false;
-            }
-
-            // If the revision doesn't have dynamic imports, then just return
-            // immediately.
-            List<BundleRequirement> dynamics =
-                Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
-            if ((dynamics == null) || dynamics.isEmpty())
-            {
-                return false;
-            }
-
-            // If the revision exports this package, then we cannot
-            // attempt to dynamically import it.
-            for (BundleCapability cap : revision.getWiring().getCapabilities(null))
-            {
-                if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                    && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
-                {
-                    return false;
-                }
-            }
-
-            // If this revision already imports or requires this package, then
-            // we cannot dynamically import it.
-            if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
-            {
-                return false;
-            }
-
-            // Loop through the importer's dynamic requirements to determine if
-            // there is a matching one for the package from which we want to
-            // load a class.
-            Map<String, Object> attrs = new HashMap(1);
-            attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
-            BundleRequirementImpl req = new BundleRequirementImpl(
-                revision,
-                BundleRevision.PACKAGE_NAMESPACE,
-                Collections.EMPTY_MAP,
-                attrs);
-            Set<BundleCapability> candidates = m_resolverState.getCandidates(req, false);
-
-            return !candidates.isEmpty();
-        }
-
-        private void markResolvedRevisions(Map<BundleRevision, List<ResolverWire>> 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)
-            {
-                // First pass: Loop through the wire map to find the host wires
-                // for any fragments and map a host to all of its fragments.
-                Map<BundleRevision, List<BundleRevision>> hosts =
-                    new HashMap<BundleRevision, List<BundleRevision>>();
-                for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
-                {
-                    BundleRevision revision = entry.getKey();
-                    List<ResolverWire> wires = entry.getValue();
-
-                    if (Util.isFragment(revision))
-                    {
-                        for (Iterator<ResolverWire> itWires = wires.iterator();
-                            itWires.hasNext(); )
-                        {
-                            ResolverWire w = itWires.next();
-                            List<BundleRevision> fragments = hosts.get(w.getProvider());
-                            if (fragments == null)
-                            {
-                                fragments = new ArrayList<BundleRevision>();
-                                hosts.put(w.getProvider(), fragments);
-                            }
-                            fragments.add(w.getRequirer());
-                        }
-                    }
-                }
-
-                // Second pass: Loop through the wire map to do three things:
-                // 1) convert resolver wires to bundle wires 2) create wiring
-                // objects for revisions and 3) record dependencies among
-                // revisions. We don't actually set the wirings here because
-                // that indicates that a revision is resolved and we don't want
-                // to mark anything as resolved unless we succussfully create
-                // all wirings.
-                Map<BundleRevision, BundleWiringImpl> wirings =
-                    new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
-                for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
-                {
-                    BundleRevision revision = entry.getKey();
-                    List<ResolverWire> resolverWires = entry.getValue();
-
-                    List<BundleWire> bundleWires =
-                        new ArrayList<BundleWire>(resolverWires.size());
-
-                    // Loop through resolver wires to calculate the package
-                    // space implied by the wires as well as to record the
-                    // dependencies.
-                    Map<String, BundleRevision> importedPkgs =
-                        new HashMap<String, BundleRevision>();
-                    Map<String, List<BundleRevision>> requiredPkgs =
-                        new HashMap<String, List<BundleRevision>>();
-                    for (ResolverWire rw : resolverWires)
-                    {
-                        bundleWires.add(
-                            new BundleWireImpl(
-                                rw.getRequirer(),
-                                rw.getRequirement(),
-                                rw.getProvider(),
-                                rw.getCapability()));
-
-                        m_dependencies.addDependent(
-                            rw.getProvider(), rw.getCapability(), rw.getRequirer());
-
-                        if (Util.isFragment(revision))
-                        {
-                            m_logger.log(
-                                Logger.LOG_DEBUG,
-                                "FRAGMENT WIRE: " + rw.toString());
-                        }
-                        else
-                        {
-                            m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
-
-                            if (rw.getCapability().getNamespace()
-                                .equals(BundleRevision.PACKAGE_NAMESPACE))
-                            {
-                                importedPkgs.put(
-                                    (String) rw.getCapability().getAttributes()
-                                        .get(BundleCapabilityImpl.PACKAGE_ATTR),
-                                    rw.getProvider());
-                            }
-                            else if (rw.getCapability().getNamespace()
-                                .equals(BundleRevision.BUNDLE_NAMESPACE))
-                            {
-                                Set<String> pkgs = calculateExportedAndReexportedPackages(
-                                        rw.getProvider(),
-                                        wireMap,
-                                        new HashSet<String>(),
-                                        new HashSet<BundleRevision>());
-                                for (String pkg : pkgs)
-                                {
-                                    List<BundleRevision> revs = requiredPkgs.get(pkg);
-                                    if (revs == null)
-                                    {
-                                        revs = new ArrayList<BundleRevision>();
-                                        requiredPkgs.put(pkg, revs);
-                                    }
-                                    revs.add(rw.getProvider());
-                                }
-                            }
-                        }
-                    }
-
-                    List<BundleRevision> fragments = hosts.get(revision);
-                    try
-                    {
-                        wirings.put(
-                            revision,
-                            new BundleWiringImpl(
-                                m_logger,
-                                m_configMap,
-                                this,
-                                (BundleRevisionImpl) revision,
-                                fragments,
-                                bundleWires,
-                                importedPkgs,
-                                requiredPkgs));
-                    }
-                    catch (Exception ex)
-                    {
-                        // This is a fatal error, so undo everything and
-                        // throw an exception.
-                        for (Entry<BundleRevision, BundleWiringImpl> wiringEntry
-                            : wirings.entrySet())
-                        {
-                            // Dispose of wiring.
-                            try
-                            {
-                                wiringEntry.getValue().dispose();
-                            }
-                            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.addRevision(revision);
-                        }
-
-                        ResolveException re = new ResolveException(
-                            "Unable to resolve " + revision,
-                            revision, null);
-                        re.initCause(ex);
-                        m_logger.log(
-                            Logger.LOG_ERROR,
-                            re.getMessage(), ex);
-                        throw re;
-                    }
-                }
-
-                // Third pass: Loop through the wire map to mark revision as resolved
-                // and update the resolver state.
-                for (Entry<BundleRevision, BundleWiringImpl> entry : wirings.entrySet())
-                {
-                    BundleRevisionImpl revision = (BundleRevisionImpl) entry.getKey();
-
-                    // Mark revision as resolved.
-                    revision.resolve(entry.getValue());
-
-                    // Update resolver state to remove substituted capabilities.
-                    if (!Util.isFragment(revision))
-                    {
-                        // Update resolver state by reindexing host with attached
-                        // fragments and removing any substituted exports.
-// TODO: OSGi R4.3 - We could avoid reindexing for fragments if we check it
-//       the revision has fragments or not.
-                        m_resolverState.addRevision(revision);
-                        m_resolverState.removeSubstitutedCapabilities(revision);
-                    }
-
-                    // Update the state of the revision's bundle to resolved as well.
-                    markBundleResolved(revision);
-                }
-            }
-        }
-
-        private void markBundleResolved(BundleRevision revision)
-        {
-            // Update the bundle's state to resolved when the
-            // current revision is resolved; just ignore resolve
-            // events for older revisions since this only occurs
-            // when an update is done on an unresolved bundle
-            // and there was no refresh performed.
-            BundleImpl bundle = (BundleImpl) revision.getBundle();
-
-            // Lock the bundle first.
-            try
-            {
-                // Acquire bundle lock.
-                try
-                {
-                    acquireBundleLock(bundle, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE);
-                }
-                catch (IllegalStateException ex)
-                {
-                    // There is nothing we can do.
-                }
-                if (bundle.getCurrentRevision() == revision)
-                {
-                    if (bundle.getState() != Bundle.INSTALLED)
-                    {
-                        m_logger.log(bundle,
-                            Logger.LOG_WARNING,
-                            "Received a resolve event for a bundle that has already been resolved.");
-                    }
-                    else
-                    {
-                        setBundleStateAndNotify(bundle, Bundle.RESOLVED);
-                    }
-                }
-            }
-            finally
-            {
-                releaseBundleLock(bundle);
-            }
-        }
-
-        private void fireResolvedEvents(Map<BundleRevision, List<ResolverWire>> wireMap)
-        {
-            if (wireMap != null)
-            {
-                Iterator<Entry<BundleRevision, List<ResolverWire>>> iter = wireMap.entrySet().iterator();
-                // Iterate over the map to fire necessary RESOLVED events.
-                while (iter.hasNext())
-                {
-                    Entry<BundleRevision, List<ResolverWire>> entry = iter.next();
-                    BundleRevision revision = entry.getKey();
-
-                    // Fire RESOLVED events for all fragments.
-                    List<BundleRevision> fragments =
-                        ((BundleWiringImpl) revision.getWiring()).getFragments();
-                    for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
-                    {
-                        fireBundleEvent(BundleEvent.RESOLVED, fragments.get(i).getBundle());
-                    }
-                    fireBundleEvent(BundleEvent.RESOLVED, revision.getBundle());
-                }
-            }
-        }
-    }
-
-    private static Set<String> calculateExportedAndReexportedPackages(
-        BundleRevision br,
-        Map<BundleRevision, List<ResolverWire>> wireMap,
-        Set<String> pkgs,
-        Set<BundleRevision> cycles)
-    {
-        if (!cycles.contains(br))
-        {
-            cycles.add(br);
-
-            // Add all exported packages.
-            for (BundleCapability cap : br.getDeclaredCapabilities(null))
-            {
-                if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    pkgs.add((String)
-                        cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
-                }
-            }
-
-            // Now check to see if any required bundles are required with reexport
-            // visibility, since we need to include those packages too.
-            if (br.getWiring() == null)
-            {
-                for (ResolverWire rw : wireMap.get(br))
-                {
-                    if (rw.getCapability().getNamespace().equals(
-                        BundleRevision.BUNDLE_NAMESPACE))
-                    {
-                        String dir = rw.getRequirement()
-                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
-                        {
-                            calculateExportedAndReexportedPackages(
-                                rw.getProvider(),
-                                wireMap,
-                                pkgs,
-                                cycles);
-                        }
-                    }
-                }
-            }
-            else
-            {
-                for (BundleWire bw : br.getWiring().getRequiredWires(null))
-                {
-                    if (bw.getCapability().getNamespace().equals(
-                        BundleRevision.BUNDLE_NAMESPACE))
-                    {
-                        String dir = bw.getRequirement()
-                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
-                        {
-                            calculateExportedAndReexportedPackages(
-                                bw.getProviderWiring().getRevision(),
-                                wireMap,
-                                pkgs,
-                                cycles);
-                        }
-                    }
-                }
-            }
-        }
-
-        return pkgs;
-    }
-
     class SystemBundleActivator implements BundleActivator
     {
         public void start(BundleContext context) throws Exception
@@ -5302,7 +4773,7 @@
      * @return <tt>true</tt> if the global lock was successfully acquired,
      *         <tt>false</tt> otherwise.
     **/
-    private boolean acquireGlobalLock()
+    boolean acquireGlobalLock()
     {
         synchronized (m_bundleLock)
         {
@@ -5358,7 +4829,7 @@
      * @throws java.lang.IllegalStateException If the calling thread does not
      *         own the global lock.
     **/
-    private void releaseGlobalLock()
+    void releaseGlobalLock()
     {
         synchronized (m_bundleLock)
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index ef1ca60..b884ec9 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -20,9 +20,7 @@
 
 import java.util.*;
 import org.apache.felix.framework.util.VersionRange;
-import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleRevision;
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index d9b4cd9..8afa535 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -25,6 +25,7 @@
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 
 import org.osgi.framework.*;
+import org.osgi.framework.hooks.resolver.ResolverHookFactory;
 import org.osgi.framework.hooks.service.*;
 import org.osgi.framework.hooks.weaving.WeavingHook;
 import org.osgi.framework.wiring.BundleCapability;
@@ -56,6 +57,7 @@
         FindHook.class,
         ListenerHook.class,
         WeavingHook.class,
+        ResolverHookFactory.class,
         URLStreamHandlerService.class,
         ContentHandler.class
     };
diff --git a/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
new file mode 100644
index 0000000..ba2426e
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/StatefulResolver.java
@@ -0,0 +1,580 @@
+/*
+ * 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.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 org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.Resolver;
+import org.apache.felix.framework.resolver.ResolverImpl;
+import org.apache.felix.framework.resolver.ResolverWire;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
+import org.apache.felix.framework.wiring.BundleWireImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+
+class StatefulResolver
+{
+    private final Felix m_felix;
+    private final Resolver m_resolver;
+    private final ResolverStateImpl m_resolverState;
+
+    StatefulResolver(Felix felix)
+    {
+        m_felix = felix;
+        m_resolver = new ResolverImpl(m_felix.getLogger());
+        m_resolverState = new ResolverStateImpl(m_felix.getLogger(),
+            (String) m_felix.getConfig().get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT));
+    }
+
+    void addRevision(BundleRevision br)
+    {
+        m_resolverState.addRevision(br);
+    }
+
+    void removeRevision(BundleRevision br)
+    {
+        m_resolverState.removeRevision(br);
+    }
+
+    Set<BundleCapability> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
+    {
+        return m_resolverState.getCandidates(req, obeyMandatory);
+    }
+
+    void resolve(BundleRevision rootRevision) 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
+        // a lock just to check if the revision is resolved, which itself
+        // is a safe read. If the revision isn't resolved, we end up double
+        // check the resolved status later.
+// TODO: OSGi R4.3 - This locking strategy here depends on how we ultimately
+//       implement getWiring(), which may change.
+        if (rootRevision.getWiring() == null)
+        {
+            // Acquire global lock.
+            boolean locked = m_felix.acquireGlobalLock();
+            if (!locked)
+            {
+                throw new ResolveException(
+                    "Unable to acquire global lock for resolve.", rootRevision, null);
+            }
+
+            Map<BundleRevision, List<ResolverWire>> wireMap = null;
+            try
+            {
+                BundleImpl bundle = (BundleImpl) rootRevision.getBundle();
+
+                // Extensions are resolved differently.
+                if (bundle.isExtension())
+                {
+                    return;
+                }
+
+                // Resolve the revision.
+                wireMap = m_resolver.resolve(
+                    m_resolverState, rootRevision, m_resolverState.getFragments());
+
+                // Mark all revisions as resolved.
+                markResolvedRevisions(wireMap);
+            }
+            finally
+            {
+                // Always release the global lock.
+                m_felix.releaseGlobalLock();
+            }
+
+            fireResolvedEvents(wireMap);
+        }
+    }
+
+    BundleRevision resolve(BundleRevision revision, String pkgName)
+        throws ResolveException
+    {
+        BundleRevision provider = null;
+
+        // We cannot dynamically import if the revision is not already resolved
+        // or if it is not allowed, so check that first. Note: We check if the
+        // dynamic import is allowed without holding any locks, but this is
+        // okay since the resolver will double check later after we have
+        // acquired the global lock below.
+        if ((revision.getWiring() != null) && isAllowedDynamicImport(revision, pkgName))
+        {
+            // Acquire global lock.
+            boolean locked = m_felix.acquireGlobalLock();
+            if (!locked)
+            {
+                throw new ResolveException(
+                    "Unable to acquire global lock for resolve.", revision, null);
+            }
+
+            Map<BundleRevision, List<ResolverWire>> wireMap = null;
+            try
+            {
+                // Double check to make sure that someone hasn't beaten us to
+                // dynamically importing the package, which can happen if two
+                // threads are racing to do so. If we have an existing wire,
+                // then just return it instead.
+                provider = ((BundleWiringImpl) revision.getWiring())
+                    .getImportedPackageSource(pkgName);
+                if (provider == null)
+                {
+                    wireMap = m_resolver.resolve(
+                        m_resolverState, revision, pkgName,
+                        m_resolverState.getFragments());
+
+                    if ((wireMap != null) && wireMap.containsKey(revision))
+                    {
+                        List<ResolverWire> dynamicWires = wireMap.remove(revision);
+                        ResolverWire dynamicWire = dynamicWires.get(0);
+
+                        // Mark all revisions as resolved.
+                        markResolvedRevisions(wireMap);
+
+                        // Dynamically add new wire to importing revision.
+                        if (dynamicWire != null)
+                        {
+                            m_felix.getDependencies().addDependent(
+                                dynamicWire.getProvider(),
+                                dynamicWire.getCapability(),
+                                revision);
+
+                            ((BundleWiringImpl) revision.getWiring())
+                                .addDynamicWire(
+                                    new BundleWireImpl(
+                                        dynamicWire.getRequirer(),
+                                        dynamicWire.getRequirement(),
+                                        dynamicWire.getProvider(),
+                                        dynamicWire.getCapability()));
+
+                            m_felix.getLogger().log(
+                                Logger.LOG_DEBUG,
+                                "DYNAMIC WIRE: " + dynamicWire);
+
+                            provider = ((BundleWiringImpl) revision.getWiring())
+                                .getImportedPackageSource(pkgName);
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                // Always release the global lock.
+                m_felix.releaseGlobalLock();
+            }
+
+            fireResolvedEvents(wireMap);
+        }
+
+        return provider;
+    }
+
+    // This method duplicates a lot of logic from:
+    // ResolverImpl.getDynamicImportCandidates()
+    boolean isAllowedDynamicImport(BundleRevision revision, String pkgName)
+    {
+        // Unresolved revisions cannot dynamically import, nor can the default
+        // package be dynamically imported.
+        if ((revision.getWiring() == null) || pkgName.length() == 0)
+        {
+            return false;
+        }
+
+        // If the revision doesn't have dynamic imports, then just return
+        // immediately.
+        List<BundleRequirement> dynamics =
+            Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
+        if ((dynamics == null) || dynamics.isEmpty())
+        {
+            return false;
+        }
+
+        // If the revision exports this package, then we cannot
+        // attempt to dynamically import it.
+        for (BundleCapability cap : revision.getWiring().getCapabilities(null))
+        {
+            if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+                && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+            {
+                return false;
+            }
+        }
+
+        // If this revision already imports or requires this package, then
+        // we cannot dynamically import it.
+        if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
+        {
+            return false;
+        }
+
+        // Loop through the importer's dynamic requirements to determine if
+        // there is a matching one for the package from which we want to
+        // load a class.
+        Map<String, Object> attrs = new HashMap(1);
+        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+        BundleRequirementImpl req = new BundleRequirementImpl(
+            revision,
+            BundleRevision.PACKAGE_NAMESPACE,
+            Collections.EMPTY_MAP,
+            attrs);
+        Set<BundleCapability> candidates = m_resolverState.getCandidates(req, false);
+
+        return !candidates.isEmpty();
+    }
+
+    private void markResolvedRevisions(Map<BundleRevision, List<ResolverWire>> 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.
+
+        // First pass.
+        if (wireMap != null)
+        {
+            // First pass: Loop through the wire map to find the host wires
+            // for any fragments and map a host to all of its fragments.
+            Map<BundleRevision, List<BundleRevision>> hosts =
+                new HashMap<BundleRevision, List<BundleRevision>>();
+            for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+            {
+                BundleRevision revision = entry.getKey();
+                List<ResolverWire> wires = entry.getValue();
+
+                if (Util.isFragment(revision))
+                {
+                    for (Iterator<ResolverWire> itWires = wires.iterator();
+                        itWires.hasNext(); )
+                    {
+                        ResolverWire w = itWires.next();
+                        List<BundleRevision> fragments = hosts.get(w.getProvider());
+                        if (fragments == null)
+                        {
+                            fragments = new ArrayList<BundleRevision>();
+                            hosts.put(w.getProvider(), fragments);
+                        }
+                        fragments.add(w.getRequirer());
+                    }
+                }
+            }
+
+            // Second pass: Loop through the wire map to do three things:
+            // 1) convert resolver wires to bundle wires 2) create wiring
+            // objects for revisions and 3) record dependencies among
+            // revisions. We don't actually set the wirings here because
+            // that indicates that a revision is resolved and we don't want
+            // to mark anything as resolved unless we succussfully create
+            // all wirings.
+            Map<BundleRevision, BundleWiringImpl> wirings =
+                new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
+            for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+            {
+                BundleRevision revision = entry.getKey();
+                List<ResolverWire> resolverWires = entry.getValue();
+
+                List<BundleWire> bundleWires =
+                    new ArrayList<BundleWire>(resolverWires.size());
+
+                // Loop through resolver wires to calculate the package
+                // space implied by the wires as well as to record the
+                // dependencies.
+                Map<String, BundleRevision> importedPkgs =
+                    new HashMap<String, BundleRevision>();
+                Map<String, List<BundleRevision>> requiredPkgs =
+                    new HashMap<String, List<BundleRevision>>();
+                for (ResolverWire rw : resolverWires)
+                {
+                    bundleWires.add(
+                        new BundleWireImpl(
+                            rw.getRequirer(),
+                            rw.getRequirement(),
+                            rw.getProvider(),
+                            rw.getCapability()));
+
+                    m_felix.getDependencies().addDependent(
+                        rw.getProvider(), rw.getCapability(), rw.getRequirer());
+
+                    if (Util.isFragment(revision))
+                    {
+                        m_felix.getLogger().log(
+                            Logger.LOG_DEBUG,
+                            "FRAGMENT WIRE: " + rw.toString());
+                    }
+                    else
+                    {
+                        m_felix.getLogger().log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
+
+                        if (rw.getCapability().getNamespace()
+                            .equals(BundleRevision.PACKAGE_NAMESPACE))
+                        {
+                            importedPkgs.put(
+                                (String) rw.getCapability().getAttributes()
+                                    .get(BundleCapabilityImpl.PACKAGE_ATTR),
+                                rw.getProvider());
+                        }
+                        else if (rw.getCapability().getNamespace()
+                            .equals(BundleRevision.BUNDLE_NAMESPACE))
+                        {
+                            Set<String> pkgs = calculateExportedAndReexportedPackages(
+                                    rw.getProvider(),
+                                    wireMap,
+                                    new HashSet<String>(),
+                                    new HashSet<BundleRevision>());
+                            for (String pkg : pkgs)
+                            {
+                                List<BundleRevision> revs = requiredPkgs.get(pkg);
+                                if (revs == null)
+                                {
+                                    revs = new ArrayList<BundleRevision>();
+                                    requiredPkgs.put(pkg, revs);
+                                }
+                                revs.add(rw.getProvider());
+                            }
+                        }
+                    }
+                }
+
+                List<BundleRevision> fragments = hosts.get(revision);
+                try
+                {
+                    wirings.put(
+                        revision,
+                        new BundleWiringImpl(
+                            m_felix.getLogger(),
+                            m_felix.getConfig(),
+                            this,
+                            (BundleRevisionImpl) revision,
+                            fragments,
+                            bundleWires,
+                            importedPkgs,
+                            requiredPkgs));
+                }
+                catch (Exception ex)
+                {
+                    // This is a fatal error, so undo everything and
+                    // throw an exception.
+                    for (Entry<BundleRevision, BundleWiringImpl> wiringEntry
+                        : wirings.entrySet())
+                    {
+                        // Dispose of wiring.
+                        try
+                        {
+                            wiringEntry.getValue().dispose();
+                        }
+                        catch (Exception ex2)
+                        {
+                            // We are in big trouble.
+                            RuntimeException rte = new RuntimeException(
+                                "Unable to clean up resolver failure.", ex2);
+                            m_felix.getLogger().log(
+                                Logger.LOG_ERROR,
+                                rte.getMessage(), ex2);
+                            throw rte;
+                        }
+
+                        // Reindex host with no fragments.
+                        m_resolverState.addRevision(revision);
+                    }
+
+                    ResolveException re = new ResolveException(
+                        "Unable to resolve " + revision,
+                        revision, null);
+                    re.initCause(ex);
+                    m_felix.getLogger().log(
+                        Logger.LOG_ERROR,
+                        re.getMessage(), ex);
+                    throw re;
+                }
+            }
+
+            // Third pass: Loop through the wire map to mark revision as resolved
+            // and update the resolver state.
+            for (Entry<BundleRevision, BundleWiringImpl> entry : wirings.entrySet())
+            {
+                BundleRevisionImpl revision = (BundleRevisionImpl) entry.getKey();
+
+                // Mark revision as resolved.
+                revision.resolve(entry.getValue());
+
+                // Update resolver state to remove substituted capabilities.
+                if (!Util.isFragment(revision))
+                {
+                    // Update resolver state by reindexing host with attached
+                    // fragments and removing any substituted exports.
+// TODO: OSGi R4.3 - We could avoid reindexing for fragments if we check it
+//       the revision has fragments or not.
+                    m_resolverState.addRevision(revision);
+                    m_resolverState.removeSubstitutedCapabilities(revision);
+                }
+
+                // Update the state of the revision's bundle to resolved as well.
+                markBundleResolved(revision);
+            }
+        }
+    }
+
+    private void markBundleResolved(BundleRevision revision)
+    {
+        // Update the bundle's state to resolved when the
+        // current revision is resolved; just ignore resolve
+        // events for older revisions since this only occurs
+        // when an update is done on an unresolved bundle
+        // and there was no refresh performed.
+        BundleImpl bundle = (BundleImpl) revision.getBundle();
+
+        // Lock the bundle first.
+        try
+        {
+            // Acquire bundle lock.
+            try
+            {
+                m_felix.acquireBundleLock(
+                    bundle, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE);
+            }
+            catch (IllegalStateException ex)
+            {
+                // There is nothing we can do.
+            }
+            if (bundle.getCurrentRevision() == revision)
+            {
+                if (bundle.getState() != Bundle.INSTALLED)
+                {
+                    m_felix.getLogger().log(bundle,
+                        Logger.LOG_WARNING,
+                        "Received a resolve event for a bundle that has already been resolved.");
+                }
+                else
+                {
+                    m_felix.setBundleStateAndNotify(bundle, Bundle.RESOLVED);
+                }
+            }
+        }
+        finally
+        {
+            m_felix.releaseBundleLock(bundle);
+        }
+    }
+
+    private void fireResolvedEvents(Map<BundleRevision, List<ResolverWire>> wireMap)
+    {
+        if (wireMap != null)
+        {
+            Iterator<Entry<BundleRevision, List<ResolverWire>>> iter = wireMap.entrySet().iterator();
+            // Iterate over the map to fire necessary RESOLVED events.
+            while (iter.hasNext())
+            {
+                Entry<BundleRevision, List<ResolverWire>> entry = iter.next();
+                BundleRevision revision = entry.getKey();
+
+                // Fire RESOLVED events for all fragments.
+                List<BundleRevision> fragments =
+                    ((BundleWiringImpl) revision.getWiring()).getFragments();
+                for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
+                {
+                    m_felix.fireBundleEvent(BundleEvent.RESOLVED, fragments.get(i).getBundle());
+                }
+                m_felix.fireBundleEvent(BundleEvent.RESOLVED, revision.getBundle());
+            }
+        }
+    }
+
+    private static Set<String> calculateExportedAndReexportedPackages(
+        BundleRevision br,
+        Map<BundleRevision, List<ResolverWire>> wireMap,
+        Set<String> pkgs,
+        Set<BundleRevision> cycles)
+    {
+        if (!cycles.contains(br))
+        {
+            cycles.add(br);
+
+            // Add all exported packages.
+            for (BundleCapability cap : br.getDeclaredCapabilities(null))
+            {
+                if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
+                {
+                    pkgs.add((String)
+                        cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+                }
+            }
+
+            // Now check to see if any required bundles are required with reexport
+            // visibility, since we need to include those packages too.
+            if (br.getWiring() == null)
+            {
+                for (ResolverWire rw : wireMap.get(br))
+                {
+                    if (rw.getCapability().getNamespace().equals(
+                        BundleRevision.BUNDLE_NAMESPACE))
+                    {
+                        String dir = rw.getRequirement()
+                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+                        {
+                            calculateExportedAndReexportedPackages(
+                                rw.getProvider(),
+                                wireMap,
+                                pkgs,
+                                cycles);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                for (BundleWire bw : br.getWiring().getRequiredWires(null))
+                {
+                    if (bw.getCapability().getNamespace().equals(
+                        BundleRevision.BUNDLE_NAMESPACE))
+                    {
+                        String dir = bw.getRequirement()
+                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+                        {
+                            calculateExportedAndReexportedPackages(
+                                bw.getProviderWiring().getRevision(),
+                                wireMap,
+                                pkgs,
+                                cycles);
+                        }
+                    }
+                }
+            }
+        }
+
+        return pkgs;
+    }
+}
\ No newline at end of file
