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 f6d2c99..88bfd9d 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -131,21 +131,6 @@
             // Remove the revision from the resolver state.
             getFramework().getResolver().removeRevision(br);
 
-            // Set fragments to null, which will remove the revision from all
-            // of its dependent fragment revisions.
-            try
-            {
-                ((BundleRevisionImpl) br).attachFragments(null);
-            }
-            catch (Exception ex)
-            {
-                getFramework().getLogger().log(
-                    br.getBundle(), Logger.LOG_ERROR, "Error detaching fragments.", ex);
-            }
-            // Set wires to null, which will remove the revision from all
-            // of its dependent revisions.
-            ((BundleRevisionImpl) br).setWires(null, null);
-
             // Close the revision's content.
             ((BundleRevisionImpl) br).close();
         }
@@ -467,8 +452,7 @@
         }
     }
 
-    private static List<BundleRevision> createLocalizationRevisionList(
-        BundleRevisionImpl bri)
+    private static List<BundleRevision> createLocalizationRevisionList(BundleRevision br)
     {
         // If the revision is a fragment, then we actually need
         // to search its host and associated fragments for its
@@ -477,19 +461,21 @@
         // version instead of the fragment itself. If there are
         // no hosts, but the revision is a fragment, then just
         // search the revision itself.
-        if (Util.isFragment(bri))
+        if (Util.isFragment(br))
         {
-            List<BundleWire> hostWires = bri.getWires();
-            if ((hostWires != null) && (hostWires.size() > 0))
+            if (br.getWiring() != null)
             {
-                bri = (BundleRevisionImpl) hostWires.get(0).getProviderWiring().getRevision();
-                for (int hostIdx = 1; hostIdx < hostWires.size(); hostIdx++)
+                List<BundleWire> hostWires = br.getWiring().getRequiredWires(null);
+                if ((hostWires != null) && (hostWires.size() > 0))
                 {
-                    if (bri.getVersion().compareTo(
-                        hostWires.get(hostIdx).getProviderWiring().getRevision().getVersion()) < 0)
+                    br = hostWires.get(0).getProviderWiring().getRevision();
+                    for (int hostIdx = 1; hostIdx < hostWires.size(); hostIdx++)
                     {
-                        bri = (BundleRevisionImpl)
-                            hostWires.get(hostIdx).getProviderWiring().getRevision();
+                        if (br.getVersion().compareTo(
+                            hostWires.get(hostIdx).getProviderWiring().getRevision().getVersion()) < 0)
+                        {
+                            br = hostWires.get(hostIdx).getProviderWiring().getRevision();
+                        }
                     }
                 }
             }
@@ -497,8 +483,8 @@
 
         // Create a list of the revision and any attached fragment revisions.
         List<BundleRevision> result = new ArrayList<BundleRevision>();
-        result.add(bri);
-        List<BundleRevision> fragments = bri.getFragments();
+        result.add(br);
+        List<BundleRevision> fragments = ((BundleWiringImpl) br.getWiring()).getFragments();
         if (fragments != null)
         {
             result.addAll(fragments);
@@ -1075,13 +1061,16 @@
         boolean used = false;
         for (int i = 0; !unresolved && !used && (i < m_revisions.size()); i++)
         {
-            List<BundleRevision> dependents =
-                ((BundleRevisionImpl) m_revisions.get(i)).getDependents();
-            for (int j = 0; (dependents != null) && (j < dependents.size()) && !used; j++)
+            if (m_revisions.get(i).getWiring() != null)
             {
-                if (dependents.get(j) != m_revisions.get(i))
+                List<BundleRevision> dependents =
+                    ((BundleRevisionImpl) m_revisions.get(i)).getDependents();
+                for (int j = 0; (dependents != null) && (j < dependents.size()) && !used; j++)
                 {
-                    used = true;
+                    if (dependents.get(j) != m_revisions.get(i))
+                    {
+                        used = true;
+                    }
                 }
             }
         }
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 032419d..1813617 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -31,7 +31,6 @@
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -45,8 +44,6 @@
 import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.cache.JarContent;
 import org.apache.felix.framework.resolver.Content;
-import org.apache.felix.framework.resolver.HostedCapability;
-import org.apache.felix.framework.resolver.HostedRequirement;
 import org.apache.felix.framework.resolver.ResolveException;
 import org.apache.felix.framework.resolver.ResolverWire;
 import org.apache.felix.framework.resolver.ResourceNotFoundException;
@@ -71,7 +68,7 @@
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 
-public class BundleRevisionImpl implements BundleRevision, BundleWiring
+public class BundleRevisionImpl implements BundleRevision
 {
     public final static int EAGER_ACTIVATION = 0;
     public final static int LAZY_ACTIVATION = 1;
@@ -90,81 +87,33 @@
     private final Version m_version;
 
     private final List<BundleCapability> m_declaredCaps;
-    private List<BundleCapability> m_resolvedCaps = null;
     private final List<BundleRequirement> m_declaredReqs;
-    private List<BundleRequirement> m_resolvedReqs = null;
-    private final List<BundleRequirement> m_declaredDynReqs;
-    private List<BundleRequirement> m_resolvedDynReqs = null;
-    private final List<R4Library> m_nativeLibraries;
+    private final List<BundleRequirement> m_declaredDynamicReqs;
+    private final List<R4Library> m_declaredNativeLibs;
     private final int m_declaredActivationPolicy;
     private final List<String> m_activationIncludes;
     private final List<String> m_activationExcludes;
 
     private final Bundle m_bundle;
 
-    private List<BundleRevision> m_fragments = null;
-    private List<BundleWire> m_wires = null;
-    private Map<String, BundleRevision> m_importedPkgs = null;
-    private Map<String, List<BundleRevision>> m_requiredPkgs = null;
     private List<BundleRevision> m_dependentImporters = new ArrayList<BundleRevision>(0);
     private List<BundleRevision> m_dependentRequirers = new ArrayList<BundleRevision>(0);
-    private volatile boolean m_isResolved = false;
 
     private Content[] m_contentPath;
-    private Content[] m_fragmentContents = null;
-    private BundleClassLoader m_classLoader;
     private boolean m_isActivationTriggered = false;
     private ProtectionDomain m_protectionDomain = null;
     private final static SecureAction m_secureAction = new SecureAction();
 
-    // Bundle-specific class loader for boot delegation.
-    private final ClassLoader m_bootClassLoader;
-    // Default class loader for boot delegation.
-    private final static ClassLoader m_defBootClassLoader;
-
-    // Statically define the default class loader for boot delegation.
-    static
-    {
-        ClassLoader cl = null;
-        try
-        {
-            Constructor ctor = m_secureAction.getDeclaredConstructor(
-                SecureClassLoader.class, new Class[] { ClassLoader.class });
-            m_secureAction.setAccesssible(ctor);
-            cl = (ClassLoader) m_secureAction.invoke(ctor, new Object[] { null });
-        }
-        catch (Throwable ex)
-        {
-            // On Android we get an exception if we set the parent class loader
-            // to null, so we will work around that case by setting the parent
-            // class loader to the system class loader in getClassLoader() below.
-            cl = null;
-            System.err.println("Problem creating boot delegation class loader: " + ex);
-        }
-        m_defBootClassLoader = cl;
-    }
+    // Bundle wiring when resolved.
+    private volatile BundleWiringImpl m_wiring = null;
 
     // Boot delegation packages.
     private final String[] m_bootPkgs;
     private final boolean[] m_bootPkgWildcards;
 
-    // Boolean flag to enable/disable implicit boot delegation.
-    private final boolean m_implicitBootDelegation;
-    // Boolean flag to enable/disable local URLs.
-    private final boolean m_useLocalURLs;
-
     // Re-usable security manager for accessing class context.
     private static SecurityManagerEx m_sm = new SecurityManagerEx();
 
-    // Thread local to detect class loading cycles.
-    private final ThreadLocal m_cycleCheck = new ThreadLocal();
-
-    // Thread local to keep track of deferred activation.
-    private static final ThreadLocal m_deferredActivation = new ThreadLocal();
-
-    // Flag indicating whether we are on an old JVM or not.
-    private volatile static boolean m_isPreJava5 = false;
-
     /**
      * This constructor is used by the extension manager, since it needs
      * a constructor that does not throw an exception.
@@ -195,16 +144,11 @@
         m_version = null;
         m_declaredCaps = Collections.EMPTY_LIST;
         m_declaredReqs = Collections.EMPTY_LIST;
-        m_declaredDynReqs = Collections.EMPTY_LIST;
-        m_nativeLibraries = null;
+        m_declaredDynamicReqs = Collections.EMPTY_LIST;
+        m_declaredNativeLibs = null;
         m_declaredActivationPolicy = EAGER_ACTIVATION;
         m_activationExcludes = null;
         m_activationIncludes = null;
-        m_implicitBootDelegation = false;
-        m_useLocalURLs =
-            (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
-                ? false : true;
-        m_bootClassLoader = m_defBootClassLoader;
     }
 
     BundleRevisionImpl(
@@ -225,28 +169,6 @@
         m_bootPkgs = bootPkgs;
         m_bootPkgWildcards = bootPkgWildcards;
 
-        m_implicitBootDelegation =
-            (m_configMap.get(FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP) == null)
-            || Boolean.valueOf(
-                (String) m_configMap.get(
-                    FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP)).booleanValue();
-
-        m_useLocalURLs =
-            (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
-                ? false : true;
-
-        ClassLoader bootLoader = m_defBootClassLoader;
-        Object map = m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
-        if (map instanceof Map)
-        {
-            Object l = ((Map) map).get(bundle);
-            if (l instanceof ClassLoader)
-            {
-                bootLoader = (ClassLoader) l;
-            }
-        }
-        m_bootClassLoader = bootLoader;
-
         ManifestParser mp = new ManifestParser(m_logger, m_configMap, this, m_headerMap);
 
         // Record some of the parsed metadata. Note, if this is an extension
@@ -256,8 +178,8 @@
         m_version = mp.getBundleVersion();
         m_declaredCaps = mp.isExtension() ? null : mp.getCapabilities();
         m_declaredReqs = mp.getRequirements();
-        m_declaredDynReqs = mp.getDynamicRequirements();
-        m_nativeLibraries = mp.getLibraries();
+        m_declaredDynamicReqs = mp.getDynamicRequirements();
+        m_declaredNativeLibs = mp.getLibraries();
         m_declaredActivationPolicy = mp.getActivationPolicy();
         m_activationExcludes = (mp.getActivationExcludeDirective() == null)
             ? null
@@ -269,6 +191,42 @@
         m_isExtension = mp.isExtension();
     }
 
+    int getDeclaredActivationPolicy()
+    {
+        return m_declaredActivationPolicy;
+    }
+
+    List<String> getActivationExcludes()
+    {
+        return m_activationExcludes;
+    }
+
+    List<String> getActivationIncludes()
+    {
+        return m_activationIncludes;
+    }
+
+    URLStreamHandler getURLStreamHandler()
+    {
+        return m_streamHandler;
+    }
+
+    // TODO: OSGi R4.3 - Figure out how to handle this. Here we provide access
+    //       needed for BundleWiringImpl, but for implicit boot delegation property
+    //       we store it in BundleWiringImpl.
+    String[] getBootDelegationPackages()
+    {
+        return m_bootPkgs;
+    }
+
+    // TODO: OSGi R4.3 - Figure out how to handle this. Here we provide access
+    //       needed for BundleWiringImpl, but for implicit boot delegation property
+    //       we store it in BundleWiringImpl.
+    boolean[] getBootDelegationPackageWildcards()
+    {
+        return m_bootPkgWildcards;
+    }
+
     //
     // BundleRevision methods.
     //
@@ -283,7 +241,7 @@
         return m_version;
     }
 
-    public synchronized List<BundleCapability> getDeclaredCapabilities(String namespace)
+    public List<BundleCapability> getDeclaredCapabilities(String namespace)
     {
         List<BundleCapability> result = m_declaredCaps;
         if (namespace != null)
@@ -300,7 +258,7 @@
         return result;
     }
 
-    public synchronized List<BundleRequirement> getDeclaredRequirements(String namespace)
+    public List<BundleRequirement> getDeclaredRequirements(String namespace)
     {
         List<BundleRequirement> result = m_declaredReqs;
         if (namespace != null)
@@ -317,11 +275,6 @@
         return result;
     }
 
-    public synchronized List<BundleRequirement> getDeclaredDynamicRequirements()
-    {
-        return m_declaredDynReqs;
-    }
-
     public int getTypes()
     {
         if (getHeaders().containsKey(Constants.FRAGMENT_HOST))
@@ -333,7 +286,7 @@
 
     public BundleWiring getWiring()
     {
-        return (m_isResolved) ? this : null;
+        return m_wiring;
     }
 
     public Bundle getBundle()
@@ -342,182 +295,9 @@
     }
 
     //
-    // BundleWiring methods.
-    //
-
-    public boolean isCurrent()
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public boolean isInUse()
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public synchronized List<BundleCapability> getCapabilities(String namespace)
-    {
-        if (m_isResolved && (m_resolvedCaps == null))
-        {
-            List capList = (m_declaredCaps == null)
-                ? new ArrayList<BundleCapability>()
-                : new ArrayList<BundleCapability>(m_declaredCaps);
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
-            {
-                List<BundleCapability> caps =
-                    m_fragments.get(fragIdx).getDeclaredCapabilities(null);
-                for (int capIdx = 0;
-                    (caps != null) && (capIdx < caps.size());
-                    capIdx++)
-                {
-                    if (caps.get(capIdx).getNamespace().equals(
-                        BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                    {
-                        capList.add(
-                            new HostedCapability(
-                                this, (BundleCapabilityImpl) caps.get(capIdx)));
-                    }
-                }
-            }
-            m_resolvedCaps = Collections.unmodifiableList(capList);
-        }
-        List<BundleCapability> result = m_resolvedCaps;
-        if (namespace != null)
-        {
-            result = new ArrayList<BundleCapability>();
-            for (BundleCapability cap : m_resolvedCaps)
-            {
-                if (cap.getNamespace().equals(namespace))
-                {
-                    result.add(cap);
-                }
-            }
-        }
-        return result;
-    }
-
-    public synchronized List<BundleRequirement> getRequirements(String namespace)
-    {
-        if (m_isResolved && (m_resolvedReqs == null))
-        {
-            List<BundleRequirement> reqList = (m_declaredReqs == null)
-                ? new ArrayList() : new ArrayList(m_declaredReqs);
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
-            {
-                List<BundleRequirement> reqs =
-                    m_fragments.get(fragIdx).getDeclaredRequirements(null);
-                for (int reqIdx = 0;
-                    (reqs != null) && (reqIdx < reqs.size());
-                    reqIdx++)
-                {
-                    if (reqs.get(reqIdx).getNamespace().equals(
-                            BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                        || reqs.get(reqIdx).getNamespace().equals(
-                            BundleCapabilityImpl.BUNDLE_NAMESPACE))
-                    {
-                        reqList.add(
-                            new HostedRequirement(
-                                this, (BundleRequirementImpl) reqs.get(reqIdx)));
-                    }
-                }
-            }
-            m_resolvedReqs = Collections.unmodifiableList(reqList);
-        }
-        List<BundleRequirement> result = m_resolvedReqs;
-        if (namespace != null)
-        {
-            result = new ArrayList<BundleRequirement>();
-            for (BundleRequirement req : m_resolvedReqs)
-            {
-                if (req.getNamespace().equals(namespace))
-                {
-                    result.add(req);
-                }
-            }
-        }
-        return result;
-    }
-
-    public List<BundleWire> getProvidedWires(String namespace)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public List<BundleWire> getRequiredWires(String namespace)
-    {
-        return m_wires;
-    }
-
-    public BundleRevision getRevision()
-    {
-        return this;
-    }
-
-    public synchronized ClassLoader getClassLoader()
-    {
-        if (m_classLoader == null)
-        {
-            // Determine which class loader to use based on which
-            // Java platform we are running on.
-            Class clazz;
-            if (m_isPreJava5)
-            {
-                clazz = BundleClassLoader.class;
-            }
-            else
-            {
-                try
-                {
-                    clazz = BundleClassLoaderJava5.class;
-                }
-                catch (Throwable th)
-                {
-                    // If we are on pre-Java5 then we will get a verify error
-                    // here since we try to override a getResources() which is
-                    // a final method in pre-Java5.
-                    m_isPreJava5 = true;
-                    clazz = BundleClassLoader.class;
-                }
-            }
-
-            // Use SecureAction to create the class loader if security is
-            // enabled; otherwise, create it directly.
-            try
-            {
-                Constructor ctor = (Constructor) m_secureAction.getConstructor(
-                    clazz, new Class[] { BundleRevisionImpl.class, ClassLoader.class });
-                m_classLoader = (BundleClassLoader)
-                    m_secureAction.invoke(ctor,
-                    new Object[] { this, determineParentClassLoader() });
-            }
-            catch (Exception ex)
-            {
-                throw new RuntimeException("Unable to create module class loader: "
-                    + ex.getMessage() + " [" + ex.getClass().getName() + "]");
-            }
-        }
-        return m_classLoader;
-    }
-
-    public List<URL> findEntries(String path, String filePattern, int options)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public Collection<String> listResources(String path, String filePattern, int options)
-    {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    //
     // Implementating details.
     //
 
-
     public Map getHeaders()
     {
         return m_headerMap;
@@ -533,75 +313,14 @@
         return m_manifestVersion;
     }
 
-    public synchronized List<BundleRequirement> getResolvedDynamicRequirements()
+    public List<BundleRequirement> getDeclaredDynamicRequirements()
     {
-        if (m_isResolved && (m_resolvedDynReqs == null))
-        {
-            List<BundleRequirement> reqList = (m_declaredDynReqs == null)
-                ? new ArrayList() : new ArrayList(m_declaredDynReqs);
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
-            {
-                List<BundleRequirement> reqs =
-                    ((BundleRevisionImpl) m_fragments.get(fragIdx))
-                        .getDeclaredDynamicRequirements();
-                for (int reqIdx = 0;
-                    (reqs != null) && (reqIdx < reqs.size());
-                    reqIdx++)
-                {
-                    if (reqs.get(reqIdx).getNamespace().equals(
-                        BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                    {
-                        reqList.add(reqs.get(reqIdx));
-                    }
-                }
-            }
-            m_resolvedDynReqs = Collections.unmodifiableList(reqList);
-        }
-        return m_resolvedDynReqs;
+        return m_declaredDynamicReqs;
     }
 
-    public synchronized List<R4Library> getNativeLibraries()
+    public List<R4Library> getDeclaredNativeLibraries()
     {
-        List<R4Library> result = null;
-        if (m_isResolved)
-        {
-            List<R4Library> nativeList = (m_nativeLibraries == null)
-                ? new ArrayList() : new ArrayList(m_nativeLibraries);
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
-            {
-                List<R4Library> libs =
-                    ((BundleRevisionImpl) m_fragments.get(fragIdx))
-                        .getNativeLibraries();
-                for (int reqIdx = 0;
-                    (libs != null) && (reqIdx < libs.size());
-                    reqIdx++)
-                {
-                    nativeList.add(libs.get(reqIdx));
-                }
-            }
-
-            // We need to return null here if we don't have any libraries, since a
-            // zero-length array is used to indicate that matching native libraries
-            // could not be found when resolving the bundle.
-            result = (nativeList.isEmpty())
-                ? null
-                : Collections.unmodifiableList(nativeList);
-        }
-        else
-        {
-            result = m_nativeLibraries;
-        }
-
-        return result;
-    }
-
-    public int getDeclaredActivationPolicy()
-    {
-        return m_declaredActivationPolicy;
+        return m_declaredNativeLibs;
     }
 
     synchronized boolean isActivationTriggered()
@@ -643,196 +362,31 @@
         return m_id;
     }
 
-// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
-//       resolver to determine if a bundle can dynamically import.
-    public synchronized boolean hasPackageSource(String pkgName)
-    {
-        return (m_importedPkgs.containsKey(pkgName) || m_requiredPkgs.containsKey(pkgName));
-    }
-
-// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
-//       to implement dynamic imports.
-    public synchronized BundleRevision getImportedPackageSource(String pkgName)
-    {
-        return m_importedPkgs.get(pkgName);
-    }
-
-    private synchronized List<BundleRevision> getRequiredPackageSources(String pkgName)
-    {
-        return m_requiredPkgs.get(pkgName);
-    }
-
-    public synchronized List<BundleWire> getWires()
-    {
-        return m_wires;
-    }
-
-    public synchronized void addDynamicWire(ResolverWire rw)
-    {
-        // 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.
-
-        BundleWire wire = new BundleWireImpl(
-            rw.getRequirer(),
-            rw.getRequirement(),
-            rw.getProvider(),
-            rw.getCapability());
-        m_wires.add(wire);
-        m_importedPkgs.put(
-            (String) wire.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
-            rw.getProvider());
-        
-// TODO: OSGi R4.3 - What's the correct way to handle this?
-//                ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-//                    .addDependentImporter(this);
-        ((BundleRevisionImpl) rw.getProvider()).addDependentImporter(this);
-    }
-
-    public synchronized void setWires(
+    public synchronized void resolve(
+        List<BundleRevision> fragments,
         List<ResolverWire> rws,
         Map<ResolverWire, Set<String>> requiredPkgWires)
+        throws Exception
     {
         // 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.
 
-        // For fragments we don't need to capture any additional dependency
-        // information, since the wires are sufficient, so just record the
-        // new wires. The wires are to the hosts to which the fragment is attached.
-        boolean isFragment = Util.isFragment(this);
-
-        // Fragments are allowed to add new wires to existing wires, but
-        // normal bundles should never be wired again if they already 
-        // have wires.
-        if (!isFragment && (m_wires != null) && (rws != null))
+        // If there is an existing wiring, then dispose of it, which will
+        // remove any dependencies on other wirings.
+        if (m_wiring != null)
         {
-            throw new IllegalStateException("The revision already has wires.");
+            m_wiring.dispose();
+            m_wiring = null;
         }
 
-        // Convert resolver wires to bundle wires and aggregate all imported
-        // or required packages.
-        List<BundleWire> wires = null;
-        Map<String, BundleRevision> importedPkgs = null;
-        Map<String, List<BundleRevision>> requiredPkgs = null;
         if (rws != null)
         {
-            wires = new ArrayList<BundleWire>(rws.size());
-            importedPkgs = new HashMap<String, BundleRevision>();
-            requiredPkgs = new HashMap<String, List<BundleRevision>>();
-
-            for (ResolverWire rw : rws)
-            {
-                wires.add(
-                    new BundleWireImpl(
-                        rw.getRequirer(),
-                        rw.getRequirement(),
-                        rw.getProvider(),
-                        rw.getCapability()));
-
-                if (isFragment)
-                {
-                    m_logger.log(
-                        Logger.LOG_DEBUG,
-                        "FRAGMENT WIRE: "
-                        + this + " -> hosted by -> " + rw.getProvider());
-                }
-                else
-                {
-                    m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
-
-                    if (rw.getCapability().getNamespace()
-                        .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                    {
-                        importedPkgs.put(
-                            (String) rw.getCapability().getAttributes()
-                                .get(BundleCapabilityImpl.PACKAGE_ATTR),
-                            rw.getProvider());
-                    }
-                    else if (rw.getCapability().getNamespace()
-                        .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-                    {
-                        for (String pkgName : requiredPkgWires.get(rw))
-                        {
-                            List<BundleRevision> revs = requiredPkgs.get(pkgName);
-                            if (revs != null)
-                            {
-                                revs.add(rw.getProvider());
-                            }
-                            else
-                            {
-                                revs = new ArrayList<BundleRevision>();
-                                revs.add(rw.getProvider());
-                                requiredPkgs.put(pkgName, revs);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // 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; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
-        {
-            if (m_wires.get(i).getCapability().getNamespace()
-                .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-            {
-                ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-                    .removeDependentRequirer(this);
-            }
-            else if (m_wires.get(i).getCapability().getNamespace()
-                .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-                ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-                    .removeDependentImporter(this);
-            }
-        }
-
-        // If we already have wires, then add new wires to existing list (this
-        // should only happen for fragments). Otherwise, simply set wires value.
-        if ((m_wires != null) && (wires != null))
-        {
-            m_wires.addAll(wires);
-        }
-        else
-        {
-            m_wires = wires;
-        }
-        m_importedPkgs = importedPkgs;
-        m_requiredPkgs = requiredPkgs;
-
-        // Add ourself as a dependent to the new wires' modules.
-        if (!isFragment && (rws != null))
-        {
-            for (ResolverWire rw : rws)
-            {
-                if (rw.getCapability().getNamespace()
-                    .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-                {
-                    ((BundleRevisionImpl) rw.getProvider()).addDependentRequirer(this);
-                }
-                else if (rw.getCapability().getNamespace()
-                    .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                {
-                    ((BundleRevisionImpl) rw.getProvider()).addDependentImporter(this);
-                }
-            }
+            m_wiring = new BundleWiringImpl(
+                m_logger, m_configMap, m_resolver, this, fragments, rws, requiredPkgWires);
         }
     }
 
-    public boolean isResolved()
-    {
-        return m_isResolved;
-    }
-
-    public void setResolved()
-    {
-        m_isResolved = true;
-    }
-
-
     public synchronized void setSecurityContext(Object securityContext)
     {
         m_protectionDomain = (ProtectionDomain) securityContext;
@@ -883,10 +437,6 @@
     {
         List contentList = new ArrayList();
         calculateContentPath(this, m_content, contentList, true);
-        for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
-        {
-            calculateContentPath(m_fragments.get(i), m_fragmentContents[i], contentList, false);
-        }
         return (Content[]) contentList.toArray(new Content[contentList.size()]);
     }
 
@@ -933,17 +483,6 @@
                 // Try to find the embedded class path entry in the current
                 // content.
                 Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
-                // If the embedded class path entry was not found, it might be
-                // in one of the fragments if the current content is the bundle,
-                // so try to search the fragments if necessary.
-                for (int fragIdx = 0;
-                    searchFragments && (embeddedContent == null)
-                        && (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
-                    fragIdx++)
-                {
-                    embeddedContent =
-                        m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings.get(i));
-                }
                 // If we found the embedded content, then add it to the
                 // class path content list.
                 if (embeddedContent != null)
@@ -973,170 +512,6 @@
         return contentList;
     }
 
-    public Class getClassByDelegation(String name) throws ClassNotFoundException
-    {
-        // We do not call getClassLoader().loadClass() for arrays because
-        // it does not correctly handle array types, which is necessary in
-        // cases like deserialization using a wrapper class loader.
-        if ((name != null) && (name.length() > 0) && (name.charAt(0) == '['))
-        {
-            return Class.forName(name, false, getClassLoader());
-        }
-        return getClassLoader().loadClass(name);
-    }
-
-    public URL getResourceByDelegation(String name)
-    {
-        try
-        {
-            return (URL) findClassOrResourceByDelegation(name, false);
-        }
-        catch (ClassNotFoundException ex)
-        {
-            // This should never be thrown because we are loading resources.
-        }
-        catch (ResourceNotFoundException ex)
-        {
-            m_logger.log(m_bundle,
-                Logger.LOG_DEBUG,
-                ex.getMessage());
-        }
-        return null;
-    }
-
-    private Object findClassOrResourceByDelegation(String name, boolean isClass)
-        throws ClassNotFoundException, ResourceNotFoundException
-    {
-        Object result = null;
-
-        Set requestSet = (Set) m_cycleCheck.get();
-        if (requestSet == null)
-        {
-            requestSet = new HashSet();
-            m_cycleCheck.set(requestSet);
-        }
-        if (requestSet.add(name))
-        {
-            try
-            {
-                // First, try to resolve the originating revision.
-                m_resolver.resolve(this);
-
-                // Get the package of the target class/resource.
-                String pkgName = (isClass)
-                    ? Util.getClassPackage(name)
-                    : Util.getResourcePackage(name);
-
-                // Delegate any packages listed in the boot delegation
-                // property to the parent class loader.
-                if (shouldBootDelegate(pkgName))
-                {
-                    try
-                    {
-                        // Get the appropriate class loader for delegation.
-                        ClassLoader bdcl = getBootDelegationClassLoader();
-                        result = (isClass)
-                            ? (Object) bdcl.loadClass(name)
-                            : (Object) bdcl.getResource(name);
-                        // If this is a java.* package, then always terminate the
-                        // search; otherwise, continue to look locally if not found.
-                        if (pkgName.startsWith("java.") || (result != null))
-                        {
-                            return result;
-                        }
-                    }
-                    catch (ClassNotFoundException ex)
-                    {
-                        // If this is a java.* package, then always terminate the
-                        // search; otherwise, continue to look locally if not found.
-                        if (pkgName.startsWith("java."))
-                        {
-                            throw ex;
-                        }
-                    }
-                }
-
-                // Look in the revision's imports. Note that the search may
-                // be aborted if this method throws an exception, otherwise
-                // it continues if a null is returned.
-                result = searchImports(pkgName, name, isClass);
-
-                // If not found, try the revision's own class path.
-                if (result == null)
-                {
-                    result = (isClass)
-                        ? (Object) ((BundleClassLoader) getClassLoader()).findClass(name)
-                        : (Object) getResourceLocal(name);
-
-                    // If still not found, then try the revision's dynamic imports.
-                    if (result == null)
-                    {
-                        result = searchDynamicImports(pkgName, name, isClass);
-                    }
-                }
-            }
-            catch (ResolveException ex)
-            {
-                if (isClass)
-                {
-                    // We do not use the resolve exception as the
-                    // cause of the exception, since this would
-                    // potentially leak internal module information.
-                    throw new ClassNotFoundException(
-                        name + " not found because "
-                        + getBundle()
-                        + " cannot resolve: "
-                        + ex.getRequirement());
-                }
-                else
-                {
-                    // The spec states that if the bundle cannot be resolved, then
-                    // only the local bundle's resources should be searched. So we
-                    // will ask the module's own class path.
-                    URL url = getResourceLocal(name);
-                    if (url != null)
-                    {
-                        return url;
-                    }
-
-                    // We need to throw a resource not found exception.
-                    throw new ResourceNotFoundException(
-                        name + " not found because "
-                        + getBundle()
-                        + " cannot resolve: "
-                        + ex.getRequirement());
-                }
-            }
-            finally
-            {
-                requestSet.remove(name);
-            }
-        }
-        else
-        {
-            // If a cycle is detected, we should return null to break the
-            // cycle. This should only ever be return to internal class
-            // loading code and not to the actual instigator of the class load.
-            return null;
-        }
-
-        if (result == null)
-        {
-            if (isClass)
-            {
-                throw new ClassNotFoundException(
-                    name + " not found by " + this.getBundle());
-            }
-            else
-            {
-                throw new ResourceNotFoundException(
-                    name + " not found by " + this.getBundle());
-            }
-        }
-
-        return result;
-    }
-
     URL getResourceLocal(String name)
     {
         URL url = null;
@@ -1169,159 +544,7 @@
         return url;
     }
 
-    public Enumeration getResourcesByDelegation(String name)
-    {
-        Set requestSet = (Set) m_cycleCheck.get();
-        if (requestSet == null)
-        {
-            requestSet = new HashSet();
-            m_cycleCheck.set(requestSet);
-        }
-        if (!requestSet.contains(name))
-        {
-            requestSet.add(name);
-            try
-            {
-                return findResourcesByDelegation(name);
-            }
-            finally
-            {
-                requestSet.remove(name);
-            }
-        }
-
-        return null;
-    }
-
-    private Enumeration findResourcesByDelegation(String name)
-    {
-        Enumeration urls = null;
-        List completeUrlList = new ArrayList();
-
-        // First, try to resolve the originating module.
-        try
-        {
-            m_resolver.resolve(this);
-        }
-        catch (ResolveException ex)
-        {
-            // The spec states that if the bundle cannot be resolved, then
-            // only the local bundle's resources should be searched. So we
-            // will ask the module's own class path.
-            return getResourcesLocal(name);
-        }
-
-        // Get the package of the target class/resource.
-        String pkgName = Util.getResourcePackage(name);
-
-        // Delegate any packages listed in the boot delegation
-        // property to the parent class loader.
-        if (shouldBootDelegate(pkgName))
-        {
-            try
-            {
-                // Get the appropriate class loader for delegation.
-                ClassLoader bdcl = getBootDelegationClassLoader();
-                urls = bdcl.getResources(name);
-            }
-            catch (IOException ex)
-            {
-                // This shouldn't happen and even if it does, there
-                // is nothing we can do, so just ignore it.
-            }
-            // If this is a java.* package, then always terminate the
-            // search; otherwise, continue to look locally.
-            if (pkgName.startsWith("java."))
-            {
-                return urls;
-            }
-
-            completeUrlList.add(urls);
-        }
-
-        // Look in the revisions's imported packages. If the package is
-        // imported, then we stop searching no matter the result since
-        // imported packages cannot be split.
-        BundleRevision provider = getImportedPackageSource(pkgName);
-        if (provider != null)
-        {
-            // Delegate to the provider revision.
-            urls = ((BundleRevisionImpl) provider).getResourcesByDelegation(name);
-
-            // If we find any resources, then add them.
-            if ((urls != null) && (urls.hasMoreElements()))
-            {
-                completeUrlList.add(urls);
-            }
-
-            // Always return here since imported packages cannot be split
-            // across required bundles or the revision's content.
-            return new CompoundEnumeration((Enumeration[])
-                completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
-        }
-
-        // See whether we can get the resource from the required bundles and
-        // regardless of whether or not this is the case continue to the next
-        // step potentially passing on the result of this search (if any).
-        List<BundleRevision> providers = getRequiredPackageSources(pkgName);
-        if (providers != null)
-        {
-            for (BundleRevision p : providers)
-            {
-                // Delegate to the provider revision.
-                urls = ((BundleRevisionImpl) p).getResourcesByDelegation(name);
-
-                // If we find any resources, then add them.
-                if ((urls != null) && (urls.hasMoreElements()))
-                {
-                    completeUrlList.add(urls);
-                }
-
-                // Do not return here, since required packages can be split
-                // across the revision's content.
-            }
-        }
-
-        // Try the module's own class path. If we can find the resource then
-        // return it together with the results from the other searches else
-        // try to look into the dynamic imports.
-        urls = getResourcesLocal(name);
-        if ((urls != null) && (urls.hasMoreElements()))
-        {
-            completeUrlList.add(urls);
-        }
-        else
-        {
-            // If not found, then try the module's dynamic imports.
-            // At this point, the module's imports were searched and so was the
-            // the module's content. Now we make an attempt to load the
-            // class/resource via a dynamic import, if possible.
-            try
-            {
-                provider = m_resolver.resolve(this, pkgName);
-            }
-            catch (ResolveException ex)
-            {
-                // Ignore this since it is likely normal.
-            }
-            if (provider != null)
-            {
-                // Delegate to the provider revision.
-                urls = ((BundleRevisionImpl) provider).getResourcesByDelegation(name);
-
-                // If we find any resources, then add them.
-                if ((urls != null) && (urls.hasMoreElements()))
-                {
-                    completeUrlList.add(urls);
-                }
-            }
-        }
-
-        return new CompoundEnumeration((Enumeration[])
-            completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
-    }
-
-    private Enumeration getResourcesLocal(String name)
+    Enumeration getResourcesLocal(String name)
     {
         List l = new ArrayList();
 
@@ -1461,102 +684,6 @@
         return null;
     }
 
-    //
-    // Fragment and dependency management methods.
-    //
-
-    public synchronized List<BundleRevision> getFragments()
-    {
-        return m_fragments;
-    }
-
-    private synchronized void detachHost(BundleRevision host)
-    {
-        if (m_wires != null)
-        {
-            for (Iterator<BundleWire> it = m_wires.iterator(); it.hasNext(); )
-            {
-                BundleWire wire = it.next();
-                if (wire.getCapability().getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE)
-                    && wire.getProviderWiring().getRevision().equals(host))
-                {
-                    it.remove();
-                    break;
-                }
-            }
-        }
-    }
-
-    public synchronized void attachFragments(List<BundleRevision> fragments) throws Exception
-    {
-        // Remove the host wires for this module from old fragments.
-        // We will generally only remove host wires when we are uninstalling
-        // the module.
-        if (m_fragments != null)
-        {
-            for (BundleRevision fragment : m_fragments)
-            {
-                ((BundleRevisionImpl) fragment).detachHost(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_resolvedCaps = null;
-        m_resolvedReqs = null;
-        m_resolvedDynReqs = null;
-
-        // Update the dependencies on the new fragments.
-        m_fragments = fragments;
-
-        // 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)
-        {
-            // 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, BundleRevision> sorted = new TreeMap<String, BundleRevision>();
-                for (BundleRevision f : m_fragments)
-                {
-                    sorted.put(((BundleRevisionImpl) 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++)
-            {
-                m_fragmentContents[i] =
-                    ((BundleRevisionImpl) m_fragments.get(i)).getContent()
-                        .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
-            }
-            // Recalculate the content path for the new fragments.
-            m_contentPath = initializeContentPath();
-        }
-    }
-
     public synchronized List<BundleRevision> getDependentImporters()
     {
         return m_dependentImporters;
@@ -1599,9 +726,11 @@
         if (Util.isFragment(this))
         {
             dependents = new ArrayList<BundleRevision>();
-            for (int i = 0; (m_wires != null) && (i < m_wires.size()); i++)
+            List<BundleWire> wires = (m_wiring == null)
+                ? null : m_wiring.getRequiredWires(null);
+            for (int i = 0; (wires != null) && (i < wires.size()); i++)
             {
-                dependents.add(m_wires.get(i).getCapability().getRevision());
+                dependents.add(wires.get(i).getProviderWiring().getRevision());
             }
         }
         else
@@ -1616,18 +745,20 @@
 
     public synchronized void close()
     {
+        try
+        {
+            resolve(null, null, null);
+        }
+        catch (Exception ex)
+        {
+            m_logger.log(Logger.LOG_ERROR, "Error releasing revision: " + ex.getMessage(), ex);
+        }
         m_content.close();
         for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
         {
             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;
     }
 
     @Override
@@ -1636,815 +767,6 @@
         return m_id;
     }
 
-    private ClassLoader determineParentClassLoader()
-    {
-        // Determine the class loader's parent based on the
-        // configuration property; use boot class loader by
-        // default.
-        String cfg = (String) m_configMap.get(Constants.FRAMEWORK_BUNDLE_PARENT);
-        cfg = (cfg == null) ? Constants.FRAMEWORK_BUNDLE_PARENT_BOOT : cfg;
-        final ClassLoader parent;
-        if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_APP))
-        {
-            parent = m_secureAction.getSystemClassLoader();
-        }
-        else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_EXT))
-        {
-            parent = m_secureAction.getParentClassLoader(m_secureAction.getSystemClassLoader());
-        }
-        else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK))
-        {
-            parent = m_secureAction.getClassLoader(BundleRevisionImpl.class);
-        }
-        // On Android we cannot set the parent class loader to be null, so
-        // we special case that situation here and set it to the system
-        // class loader by default instead, which is not really spec.
-        else if (m_bootClassLoader == null)
-        {
-            parent = m_secureAction.getSystemClassLoader();
-        }
-        else
-        {
-            parent = null;
-        }
-        return parent;
-    }
-
-    private Object searchImports(String pkgName, String name, boolean isClass)
-        throws ClassNotFoundException, ResourceNotFoundException
-    {
-        // Check if the package is imported.
-        BundleRevision provider = getImportedPackageSource(pkgName);
-        if (provider != null)
-        {
-            // If we find the class or resource, then return it.
-            Object result = (isClass)
-                ? (Object) ((BundleRevisionImpl) provider).getClassByDelegation(name)
-                : (Object) ((BundleRevisionImpl) provider).getResourceByDelegation(name);
-            if (result != null)
-            {
-                return result;
-            }
-
-            // If no class was found, then we must throw an exception
-            // since the provider of this package did not contain the
-            // requested class and imported packages are atomic.
-            throw new ClassNotFoundException(name);
-        }
-
-        // Check if the package is required.
-        List<BundleRevision> providers = getRequiredPackageSources(pkgName);
-        if (providers != null)
-        {
-            for (BundleRevision p : providers)
-            {
-                // If we find the class or resource, then return it.
-                try
-                {
-                    Object result = (isClass)
-                        ? (Object) ((BundleRevisionImpl) p).getClassByDelegation(name)
-                        : (Object) ((BundleRevisionImpl) p).getResourceByDelegation(name);
-                    if (result != null)
-                    {
-                        return result;
-                    }
-                }
-                catch (ClassNotFoundException ex)
-                {
-                    // Since required packages can be split, don't throw an
-                    // exception here if it is not found. Instead, we'll just
-                    // continue searching other required bundles and the
-                    // revision's local content.
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private Object searchDynamicImports(
-        final String pkgName, final String name, final boolean isClass)
-        throws ClassNotFoundException, ResourceNotFoundException
-    {
-        // At this point, the module's imports were searched and so was the
-        // the module's content. Now we make an attempt to load the
-        // class/resource via a dynamic import, if possible.
-        BundleRevision provider = null;
-        try
-        {
-            provider = m_resolver.resolve(this, pkgName);
-        }
-        catch (ResolveException ex)
-        {
-            // Ignore this since it is likely normal.
-        }
-
-        // If the dynamic import was successful, then this initial
-        // time we must directly return the result from dynamically
-        // created package sources, but subsequent requests for
-        // classes/resources in the associated package will be
-        // processed as part of normal static imports.
-        if (provider != null)
-        {
-            // Return the class or resource.
-            return (isClass)
-                ? (Object) ((BundleRevisionImpl) provider).getClassByDelegation(name)
-                : (Object) ((BundleRevisionImpl) provider).getResourceByDelegation(name);
-        }
-
-        // If implicit boot delegation is enabled, then try to guess whether
-        // we should boot delegate.
-        if (m_implicitBootDelegation)
-        {
-            // At this point, the class/resource could not be found by the bundle's
-            // static or dynamic imports, nor its own content. Before we throw
-            // an exception, we will try to determine if the instigator of the
-            // class/resource load was a class from a bundle or not. This is necessary
-            // because the specification mandates that classes on the class path
-            // should be hidden (except for java.*), but it does allow for these
-            // classes/resources to be exposed by the system bundle as an export.
-            // However, in some situations classes on the class path make the faulty
-            // assumption that they can access everything on the class path from
-            // every other class loader that they come in contact with. This is
-            // not true if the class loader in question is from a bundle. Thus,
-            // this code tries to detect that situation. If the class instigating
-            // the load request was NOT from a bundle, then we will make the
-            // assumption that the caller actually wanted to use the parent class
-            // loader and we will delegate to it. If the class was
-            // from a bundle, then we will enforce strict class loading rules
-            // for the bundle and throw an exception.
-
-            // Get the class context to see the classes on the stack.
-            final Class[] classes = m_sm.getClassContext();
-            try
-            {
-                if (System.getSecurityManager() != null)
-                {
-                    return AccessController
-                        .doPrivileged(new PrivilegedExceptionAction()
-                        {
-                            public Object run() throws Exception
-                            {
-                                return doImplicitBootDelegation(classes, name,
-                                    isClass);
-                            }
-                        });
-                }
-                else
-                {
-                    return doImplicitBootDelegation(classes, name, isClass);
-                }
-            }
-            catch (PrivilegedActionException ex)
-            {
-                Exception cause = ex.getException();
-                if (cause instanceof ClassNotFoundException)
-                {
-                    throw (ClassNotFoundException) cause;
-                }
-                else
-                {
-                    throw (ResourceNotFoundException) cause;
-                }
-            }
-        }
-        return null;
-    }
-
-    private Object doImplicitBootDelegation(Class[] classes, String name, boolean isClass)
-        throws ClassNotFoundException, ResourceNotFoundException
-    {
-        // Start from 1 to skip security manager class.
-        for (int i = 1; i < classes.length; i++)
-        {
-            // Find the first class on the call stack that is not from
-            // the class loader that loaded the Felix classes or is not
-            // a class loader or class itself, because we want to ignore
-            // calls to ClassLoader.loadClass() and Class.forName() since
-            // we are trying to find out who instigated the class load.
-            // Also ignore inner classes of class loaders, since we can
-            // assume they are a class loader too.
-
-            // TODO: FRAMEWORK - This check is a hack and we should see if we can think
-            // of another way to do it, since it won't necessarily work in all situations.
-            // Since Felix uses threads for changing the start level
-            // and refreshing packages, it is possible that there are no
-            // bundle classes on the call stack; therefore, as soon as we
-            // see Thread on the call stack we exit this loop. Other cases
-            // where bundles actually use threads are not an issue because
-            // the bundle classes will be on the call stack before the
-            // Thread class.
-            if (Thread.class.equals(classes[i]))
-            {
-                break;
-            }
-            // Break if the current class came from a bundle, since we should
-            // not implicitly boot delegate in that case.
-            else if (isClassLoadedFromBundleRevision(classes[i]))
-            {
-                break;
-            }
-            // Break if this goes through BundleImpl because it must be a call
-            // to Bundle.loadClass() which should not implicitly boot delegate.
-            else if (BundleImpl.class.equals(classes[i]))
-            {
-                break;
-            }
-            else if (isClassExternal(classes[i]))
-            {
-                try
-                {
-                    // Return the class or resource from the parent class loader.
-                    return (isClass)
-                        ? (Object) m_secureAction.getClassLoader(this.getClass()).loadClass(name)
-                        : (Object) m_secureAction.getClassLoader(this.getClass()).getResource(name);
-                }
-                catch (NoClassDefFoundError ex)
-                {
-                    // Ignore, will return null
-                }
-                break;
-            }
-        }
-
-        return null;
-    }
-
-    private boolean isClassLoadedFromBundleRevision(Class clazz)
-    {
-        // The target class is loaded by a bundle class loader,
-        // then return true.
-        if (BundleClassLoader.class.isInstance(m_secureAction.getClassLoader(clazz)))
-        {
-            return true;
-        }
-
-        // If the target class was loaded from a class loader that
-        // came from a bundle, then return true.
-        ClassLoader last = null;
-        for (ClassLoader cl = m_secureAction.getClassLoader(clazz);
-            (cl != null) && (last != cl);
-            cl = m_secureAction.getClassLoader(cl.getClass()))
-        {
-            last = cl;
-            if (BundleClassLoader.class.isInstance(cl))
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Tries to determine whether the given class is part of the framework or not.
-     * Framework classes include everything in org.apache.felix.framework.* and
-     * org.osgi.framework.*. We also consider ClassLoader and Class to be internal
-     * classes, because they are inserted into the stack trace as a result of
-     * method overloading. Typically, ClassLoader or Class will be mixed in
-     * between framework classes or will be at the point where the class loading
-     * request enters the framework class loading mechanism, which will then be
-     * followed by either bundle or external code, which will then exit our
-     * attempt to determine if we should boot delegate or not. Other standard
-     * class loaders, like URLClassLoader, are considered external classes and
-     * should trigger boot delegation. This means that bundles can create standard
-     * class loaders to get access to boot packages, but this is the standard
-     * behavior of class loaders.
-     * @param clazz the class to determine if it is external or not.
-     * @return <tt>true</tt> if the class is external, otherwise <tt>false</tt>.
-     */
-    private boolean isClassExternal(Class clazz)
-    {
-        if (clazz.getName().startsWith("org.apache.felix.framework."))
-        {
-            return false;
-        }
-        else if (clazz.getName().startsWith("org.osgi.framework."))
-        {
-            return false;
-        }
-        else if (ClassLoader.class.equals(clazz))
-        {
-            return false;
-        }
-        else if (Class.class.equals(clazz))
-        {
-            return false;
-        }
-        return true;
-    }
-
-    boolean shouldBootDelegate(String pkgName)
-    {
-        // Always boot delegate if the bundle has a configured
-        // boot class loader.
-        if (m_bootClassLoader != m_defBootClassLoader)
-        {
-            return true;
-        }
-
-        boolean result = false;
-
-        // Only consider delegation if we have a package name, since
-        // we don't want to promote the default package. The spec does
-        // not take a stand on this issue.
-        if (pkgName.length() > 0)
-        {
-            for (int i = 0; !result && (i < m_bootPkgs.length); i++)
-            {
-                // Check if the boot package is wildcarded.
-                // A wildcarded boot package will be in the form "foo.",
-                // so a matching subpackage will start with "foo.", e.g.,
-                // "foo.bar".
-                if (m_bootPkgWildcards[i] && pkgName.startsWith(m_bootPkgs[i]))
-                {
-                    return true;
-                }
-                // If not wildcarded, then check for an exact match.
-                else if (m_bootPkgs[i].equals(pkgName))
-                {
-                    return true;
-                }
-            }
-        }
-
-        return result;
-    }
-
-    ClassLoader getBootDelegationClassLoader()
-    {
-        // Get the appropriate class loader for delegation.
-        ClassLoader parent = (m_classLoader == null)
-            ? determineParentClassLoader() : m_secureAction.getParentClassLoader(m_classLoader);
-        return (parent == null) ? m_bootClassLoader : parent;
-    }
-
-    private static final Constructor m_dexFileClassConstructor;
-    private static final Method m_dexFileClassLoadDex;
-    private static final Method m_dexFileClassLoadClass;
-
-    static
-    {
-        Constructor dexFileClassConstructor = null;
-        Method dexFileClassLoadDex = null;
-        Method dexFileClassLoadClass = null;
-        try
-        {
-            Class dexFileClass;
-            try
-            {
-                dexFileClass = Class.forName("dalvik.system.DexFile");
-            }
-            catch (Exception ex)
-            {
-                dexFileClass = Class.forName("android.dalvik.DexFile");
-            }
-
-            try
-            {
-                dexFileClassLoadDex = dexFileClass.getMethod("loadDex", 
-                    new Class[]{String.class, String.class, Integer.TYPE});
-            }
-            catch (Exception ex)
-            {
-                // Nothing we need to do 
-            }
-            dexFileClassConstructor = dexFileClass.getConstructor(
-                new Class[] { java.io.File.class });
-            dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
-                new Class[] { String.class, ClassLoader.class });
-        }
-        catch (Throwable ex)
-        {
-           dexFileClassConstructor = null;
-           dexFileClassLoadDex = null;
-           dexFileClassLoadClass = null;
-        }
-        m_dexFileClassConstructor = dexFileClassConstructor;
-        m_dexFileClassLoadDex= dexFileClassLoadDex;
-        m_dexFileClassLoadClass = dexFileClassLoadClass;
-    }
-
-    public class BundleClassLoaderJava5 extends BundleClassLoader
-    {
-        public BundleClassLoaderJava5(ClassLoader parent)
-        {
-            super(parent);
-        }
-
-        @Override
-        public Enumeration getResources(String name)
-        {
-            Enumeration urls = BundleRevisionImpl.this.getResourcesByDelegation(name);
-            if (m_useLocalURLs)
-            {
-                urls = new ToLocalUrlEnumeration(urls);
-            }
-            return urls;
-        }
-
-        @Override
-        protected Enumeration findResources(String name)
-        {
-            return BundleRevisionImpl.this.getResourcesLocal(name);
-        }
-    }
-
-    public class BundleClassLoader extends SecureClassLoader implements BundleReference
-    {
-        private final Map m_jarContentToDexFile;
-        private Object[][] m_cachedLibs = new Object[0][];
-        private static final int LIBNAME_IDX = 0;
-        private static final int LIBPATH_IDX = 1;
-
-        public BundleClassLoader(ClassLoader parent)
-        {
-            super(parent);
-            if (m_dexFileClassLoadClass != null)
-            {
-                m_jarContentToDexFile = new HashMap();
-            }
-            else
-            {
-                m_jarContentToDexFile = null;
-            }
-        }
-
-        public Bundle getBundle()
-        {
-            return BundleRevisionImpl.this.getBundle();
-        }
-
-        @Override
-        protected Class loadClass(String name, boolean resolve)
-            throws ClassNotFoundException
-        {
-            Class clazz = null;
-
-            // Make sure the class was not already loaded.
-            synchronized (this)
-            {
-                clazz = findLoadedClass(name);
-            }
-
-            if (clazz == null)
-            {
-                try
-                {
-                    clazz = (Class) findClassOrResourceByDelegation(name, true);
-                }
-                catch (ResourceNotFoundException ex)
-                {
-                    // This should never happen since we are asking for a class,
-                    // so just ignore it.
-                }
-                catch (ClassNotFoundException cnfe)
-                {
-                    ClassNotFoundException ex = cnfe;
-                    String msg = name;
-                    if (m_logger.getLogLevel() >= Logger.LOG_DEBUG)
-                    {
-                        msg = diagnoseClassLoadError(m_resolver, BundleRevisionImpl.this, name);
-                        ex = (msg != null)
-                            ? new ClassNotFoundException(msg, cnfe)
-                            : ex;
-                    }
-                    throw ex;
-                }
-            }
-
-            // Resolve the class and return it.
-            if (resolve)
-            {
-                resolveClass(clazz);
-            }
-            return clazz;
-        }
-
-        @Override
-        protected Class findClass(String name) throws ClassNotFoundException
-        {
-            Class clazz = null;
-
-            // Search for class in bundle revision.
-            if (clazz == null)
-            {
-                String actual = name.replace('.', '/') + ".class";
-
-                byte[] bytes = null;
-
-                // Check the bundle class path.
-                Content[] contentPath = getContentPath();
-                Content content = null;
-                for (int i = 0;
-                    (bytes == null) &&
-                    (i < contentPath.length); i++)
-                {
-                    bytes = contentPath[i].getEntryAsBytes(actual);
-                    content = contentPath[i];
-                }
-
-                if (bytes != null)
-                {
-                    // Get package name.
-                    String pkgName = Util.getClassPackage(name);
-
-                    // Before we actually attempt to define the class, grab
-                    // the lock for this class loader and make sure than no
-                    // other thread has defined this class in the meantime.
-                    synchronized (this)
-                    {
-                        clazz = findLoadedClass(name);
-
-                        if (clazz == null)
-                        {
-                            int activationPolicy = 
-                                ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
-                                ? ((BundleRevisionImpl) ((BundleImpl) getBundle())
-                                    .getCurrentRevision()).getDeclaredActivationPolicy()
-                                : EAGER_ACTIVATION;
-
-                            // If the revision is using deferred activation, then if
-                            // we load this class from this revision we need to activate
-                            // the bundle before returning the class. We will short
-                            // circuit the trigger matching if the trigger is already
-                            // tripped.
-                            boolean isTriggerClass = m_isActivationTriggered
-                                ? false : isActivationTrigger(pkgName);
-                            if (!m_isActivationTriggered
-                                && isTriggerClass
-                                && (activationPolicy == BundleRevisionImpl.LAZY_ACTIVATION)
-                                && (getBundle().getState() == Bundle.STARTING))
-                            {
-                                List deferredList = (List) m_deferredActivation.get();
-                                if (deferredList == null)
-                                {
-                                    deferredList = new ArrayList();
-                                    m_deferredActivation.set(deferredList);
-                                }
-                                deferredList.add(new Object[] { name, getBundle() });
-                            }
-                            // We need to try to define a Package object for the class
-                            // before we call defineClass() if we haven't already
-                            // created it.
-                            if (pkgName.length() > 0)
-                            {
-                                if (getPackage(pkgName) == null)
-                                {
-                                    Object[] params = definePackage(pkgName);
-                                    if (params != null)
-                                    {
-                                        definePackage(
-                                            pkgName,
-                                            (String) params[0],
-                                            (String) params[1],
-                                            (String) params[2],
-                                            (String) params[3],
-                                            (String) params[4],
-                                            (String) params[5],
-                                            null);
-                                    }
-                                    else
-                                    {
-                                        definePackage(pkgName, null, null,
-                                            null, null, null, null, null);
-                                    }
-                                }
-                            }
-
-                            // If we can load the class from a dex file do so
-                            if (content instanceof JarContent)
-                            {
-                                try
-                                {
-                                    clazz = getDexFileClass((JarContent) content, name, this);
-                                }
-                                catch (Exception ex)
-                                {
-                                    // Looks like we can't
-                                }
-                            }
-
-                            if (clazz == null)
-                            {
-                                // If we have a security context, then use it to
-                                // define the class with it for security purposes,
-                                // otherwise define the class without a protection domain.
-                                if (m_protectionDomain != null)
-                                {
-                                    clazz = defineClass(name, bytes, 0, bytes.length,
-                                        m_protectionDomain);
-                                }
-                                else
-                                {
-                                    clazz = defineClass(name, bytes, 0, bytes.length);
-                                }
-                            }
-
-                            // At this point if we have a trigger class, then the deferred
-                            // activation trigger has tripped.
-                            if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
-                            {
-                                m_isActivationTriggered = true;
-                            }
-                        }
-                    }
-
-                    // Perform deferred activation without holding the class loader lock,
-                    // if the class we are returning is the instigating class.
-                    List deferredList = (List) m_deferredActivation.get();
-                    if ((deferredList != null)
-                        && (deferredList.size() > 0)
-                        && ((Object[]) deferredList.get(0))[0].equals(name))
-                    {
-                        for (int i = deferredList.size() - 1; i >= 0; i--)
-                        {
-                            try
-                            {
-                                ((BundleImpl) ((Object[]) deferredList.get(i))[1]).getFramework().activateBundle(
-                                    (BundleImpl) ((Object[]) deferredList.get(i))[1], true);
-                            }
-                            catch (BundleException ex)
-                            {
-                                ex.printStackTrace();
-                            }
-                        }
-                        deferredList.clear();
-                    }
-                }
-            }
-
-            return clazz;
-        }
-
-        private Object[] definePackage(String pkgName)
-        {
-            String spectitle = (String) m_headerMap.get("Specification-Title");
-            String specversion = (String) m_headerMap.get("Specification-Version");
-            String specvendor = (String) m_headerMap.get("Specification-Vendor");
-            String impltitle = (String) m_headerMap.get("Implementation-Title");
-            String implversion = (String) m_headerMap.get("Implementation-Version");
-            String implvendor = (String) m_headerMap.get("Implementation-Vendor");
-            if ((spectitle != null)
-                || (specversion != null)
-                || (specvendor != null)
-                || (impltitle != null)
-                || (implversion != null)
-                || (implvendor != null))
-            {
-                return new Object[] {
-                    spectitle, specversion, specvendor, impltitle, implversion, implvendor
-                };
-            }
-            return null;
-        }
-
-        private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
-            throws Exception
-        {
-            if (m_jarContentToDexFile == null)
-            {
-                return null;
-            }
-
-            Object dexFile = null;
-
-            if (!m_jarContentToDexFile.containsKey(content))
-            {
-                try
-                {
-                    if (m_dexFileClassLoadDex != null)
-                    {
-                        dexFile = m_dexFileClassLoadDex.invoke(null, 
-                            new Object[]{content.getFile().getAbsolutePath(), 
-                                content.getFile().getAbsolutePath() + ".dex", new Integer(0)});
-                    }
-                    else
-                    {
-                        dexFile = m_dexFileClassConstructor.newInstance(
-                            new Object[] { content.getFile() });
-                    }
-                }
-                finally
-                {
-                    m_jarContentToDexFile.put(content, dexFile);
-                }
-            }
-            else
-            {
-                dexFile = m_jarContentToDexFile.get(content);
-            }
-
-            if (dexFile != null)
-            {
-                return (Class) m_dexFileClassLoadClass.invoke(dexFile,
-                    new Object[] { name.replace('.','/'), loader });
-            }
-            return null;
-        }
-
-        @Override
-        public URL getResource(String name)
-        {
-            URL url = BundleRevisionImpl.this.getResourceByDelegation(name);
-            if (m_useLocalURLs)
-            {
-                url = convertToLocalUrl(url);
-            }
-            return url;
-        }
-
-        @Override
-        protected URL findResource(String name)
-        {
-            return BundleRevisionImpl.this.getResourceLocal(name);
-        }
-
-        // The findResources() method should only look at the revision itself, but
-        // instead it tries to delegate because in Java version prior to 1.5 the
-        // getResources() method was final and could not be overridden. We should
-        // override getResources() like getResource() to make it delegate, but we
-        // can't. As a workaround, we make findResources() delegate instead.
-        @Override
-        protected Enumeration findResources(String name)
-        {
-            Enumeration urls = BundleRevisionImpl.this.getResourcesByDelegation(name);
-            if (m_useLocalURLs)
-            {
-                urls = new ToLocalUrlEnumeration(urls);
-            }
-            return urls;
-        }
-
-        @Override
-        protected String findLibrary(String name)
-        {
-            // Remove leading slash, if present.
-            if (name.startsWith("/"))
-            {
-                name = name.substring(1);
-            }
-
-            String result = null;
-            // CONCURRENCY: In the long run, we might want to break this
-            // sync block in two to avoid manipulating the cache while
-            // holding the lock, but for now we will do it the simple way.
-            synchronized (this)
-            {
-                // Check to make sure we haven't already found this library.
-                for (int i = 0; (result == null) && (i < m_cachedLibs.length); i++)
-                {
-                    if (m_cachedLibs[i][LIBNAME_IDX].equals(name))
-                    {
-                        result = (String) m_cachedLibs[i][LIBPATH_IDX];
-                    }
-                }
-
-                // If we don't have a cached result, see if we have a matching
-                // native library.
-                if (result == null)
-                {
-                    List<R4Library> libs = getNativeLibraries();
-                    for (int libIdx = 0; (libs != null) && (libIdx < libs.size()); libIdx++)
-                    {
-                        if (libs.get(libIdx).match(m_configMap, name))
-                        {
-                            // Search bundle content first for native library.
-                            result = getContent().getEntryAsNativeLibrary(
-                                libs.get(libIdx).getEntryName());
-                            // If not found, then search fragments in order.
-                            for (int i = 0;
-                                (result == null) && (m_fragmentContents != null)
-                                    && (i < m_fragmentContents.length);
-                                i++)
-                            {
-                                result = m_fragmentContents[i].getEntryAsNativeLibrary(
-                                    libs.get(libIdx).getEntryName());
-                            }
-                        }
-                    }
-
-                    // Remember the result for future requests.
-                    if (result != null)
-                    {
-                        Object[][] tmp = new Object[m_cachedLibs.length + 1][];
-                        System.arraycopy(m_cachedLibs, 0, tmp, 0, m_cachedLibs.length);
-                        tmp[m_cachedLibs.length] = new Object[] { name, result };
-                        m_cachedLibs = tmp;
-                    }
-                }
-            }
-
-            return result;
-        }
-
-        @Override
-        public String toString()
-        {
-            return BundleRevisionImpl.this.toString();
-        }
-    }
-
     static URL convertToLocalUrl(URL url)
     {
         if (url.getProtocol().equals("bundle"))
@@ -2461,281 +783,4 @@
         }
         return url;
     }
-
-    static class ToLocalUrlEnumeration implements Enumeration
-    {
-        final Enumeration m_enumeration;
-
-        ToLocalUrlEnumeration(Enumeration enumeration)
-        {
-            m_enumeration = enumeration;
-        }
-
-        public boolean hasMoreElements()
-        {
-            return m_enumeration.hasMoreElements();
-        }
-
-        public Object nextElement()
-        {
-            return convertToLocalUrl((URL) m_enumeration.nextElement());
-        }
-    }
-
-    private static String diagnoseClassLoadError(
-        StatefulResolver resolver, BundleRevisionImpl revision, String name)
-    {
-        // We will try to do some diagnostics here to help the developer
-        // deal with this exception.
-
-        // Get package name.
-        String pkgName = Util.getClassPackage(name);
-        if (pkgName.length() == 0)
-        {
-            return null;
-        }
-
-        // First, get the bundle string of the revision doing the class loader.
-        String importer = revision.getBundle().toString();
-
-        // Next, check to see if the revision imports the package.
-        List<BundleWire> wires = revision.getWires();
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
-        {
-            if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
-                wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
-            {
-                String exporter = wires.get(i).getProviderWiring().getBundle().toString();
-
-                StringBuffer sb = new StringBuffer("*** Package '");
-                sb.append(pkgName);
-                sb.append("' is imported by bundle ");
-                sb.append(importer);
-                sb.append(" from bundle ");
-                sb.append(exporter);
-                sb.append(", but the exported package from bundle ");
-                sb.append(exporter);
-                sb.append(" does not contain the requested class '");
-                sb.append(name);
-                sb.append("'. Please verify that the class name is correct in the importing bundle ");
-                sb.append(importer);
-                sb.append(" and/or that the exported package is correctly bundled in ");
-                sb.append(exporter);
-                sb.append(". ***");
-
-                return sb.toString();
-            }
-        }
-
-        // Next, check to see if the package was optionally imported and
-        // whether or not there is an exporter available.
-        List<BundleRequirement> reqs = revision.getWiring().getRequirements(null);
-/*
-* TODO: RB - Fix diagnostic message for optional imports.
-        for (int i = 0; (reqs != null) && (i < reqs.length); i++)
-        {
-            if (reqs[i].getName().equals(pkgName) && reqs[i].isOptional())
-            {
-                // Try to see if there is an exporter available.
-                IModule[] exporters = getResolvedExporters(reqs[i], true);
-                exporters = (exporters.length == 0)
-                    ? getUnresolvedExporters(reqs[i], true) : exporters;
-
-                // An exporter might be available, but it may have attributes
-                // that do not match the importer's required attributes, so
-                // check that case by simply looking for an exporter of the
-                // desired package without any attributes.
-                if (exporters.length == 0)
-                {
-                    IRequirement pkgReq = new Requirement(
-                        ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
-                    exporters = getResolvedExporters(pkgReq, true);
-                    exporters = (exporters.length == 0)
-                        ? getUnresolvedExporters(pkgReq, true) : exporters;
-                }
-
-                long expId = (exporters.length == 0)
-                    ? -1 : Util.getBundleIdFromModuleId(exporters[0].getId());
-
-                StringBuffer sb = new StringBuffer("*** Class '");
-                sb.append(name);
-                sb.append("' was not found, but this is likely normal since package '");
-                sb.append(pkgName);
-                sb.append("' is optionally imported by bundle ");
-                sb.append(impId);
-                sb.append(".");
-                if (exporters.length > 0)
-                {
-                    sb.append(" However, bundle ");
-                    sb.append(expId);
-                    if (reqs[i].isSatisfied(
-                        Util.getExportPackage(exporters[0], reqs[i].getName())))
-                    {
-                        sb.append(" does export this package. Bundle ");
-                        sb.append(expId);
-                        sb.append(" must be installed before bundle ");
-                        sb.append(impId);
-                        sb.append(" is resolved or else the optional import will be ignored.");
-                    }
-                    else
-                    {
-                        sb.append(" does export this package with attributes that do not match.");
-                    }
-                }
-                sb.append(" ***");
-
-                return sb.toString();
-            }
-        }
-*/
-        // Next, check to see if the package is dynamically imported by the revision.
-        if (resolver.isAllowedDynamicImport(revision, pkgName))
-        {
-            // Try to see if there is an exporter available.
-            Map<String, String> dirs = Collections.EMPTY_MAP;
-            Map<String, Object> attrs = new HashMap<String, Object>(1);
-            attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
-            BundleRequirementImpl req = new BundleRequirementImpl(
-                revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
-            Set<BundleCapability> exporters = resolver.getCandidates(req, false);
-
-            BundleRevision provider = null;
-            try
-            {
-                provider = resolver.resolve(revision, pkgName);
-            }
-            catch (Exception ex)
-            {
-                provider = null;
-            }
-
-            String exporter = (exporters.isEmpty())
-                ? null : exporters.iterator().next().getRevision().getBundle().toString();
-
-            StringBuffer sb = new StringBuffer("*** Class '");
-            sb.append(name);
-            sb.append("' was not found, but this is likely normal since package '");
-            sb.append(pkgName);
-            sb.append("' is dynamically imported by bundle ");
-            sb.append(importer);
-            sb.append(".");
-            if ((exporters.size() > 0) && (provider == null))
-            {
-                sb.append(" However, bundle ");
-                sb.append(exporter);
-                sb.append(" does export this package with attributes that do not match.");
-            }
-            sb.append(" ***");
-
-            return sb.toString();
-        }
-
-        // Next, check to see if there are any exporters for the package at all.
-        Map<String, String> dirs = Collections.EMPTY_MAP;
-        Map<String, Object> attrs = new HashMap<String, Object>(1);
-        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
-        BundleRequirementImpl req = new BundleRequirementImpl(
-            revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<BundleCapability> exports = resolver.getCandidates(req, false);
-        if (exports.size() > 0)
-        {
-            boolean classpath = false;
-            try
-            {
-                m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
-                classpath = true;
-            }
-            catch (NoClassDefFoundError err)
-            {
-                // Ignore
-            }
-            catch (Exception ex)
-            {
-                // Ignore
-            }
-
-            String exporter = exports.iterator().next().getRevision().getBundle().toString();
-
-            StringBuffer sb = new StringBuffer("*** Class '");
-            sb.append(name);
-            sb.append("' was not found because bundle ");
-            sb.append(importer);
-            sb.append(" does not import '");
-            sb.append(pkgName);
-            sb.append("' even though bundle ");
-            sb.append(exporter);
-            sb.append(" does export it.");
-            if (classpath)
-            {
-                sb.append(" Additionally, the class is also available from the system class loader. There are two fixes: 1) Add an import for '");
-                sb.append(pkgName);
-                sb.append("' to bundle ");
-                sb.append(importer);
-                sb.append("; imports are necessary for each class directly touched by bundle code or indirectly touched, such as super classes if their methods are used. ");
-                sb.append("2) Add package '");
-                sb.append(pkgName);
-                sb.append("' to the '");
-                sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
-                sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
-            }
-            else
-            {
-                sb.append(" To resolve this issue, add an import for '");
-                sb.append(pkgName);
-                sb.append("' to bundle ");
-                sb.append(importer);
-                sb.append(".");
-            }
-            sb.append(" ***");
-
-            return sb.toString();
-        }
-
-        // Next, try to see if the class is available from the system
-        // class loader.
-        try
-        {
-            m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
-
-            StringBuffer sb = new StringBuffer("*** Package '");
-            sb.append(pkgName);
-            sb.append("' is not imported by bundle ");
-            sb.append(importer);
-            sb.append(", nor is there any bundle that exports package '");
-            sb.append(pkgName);
-            sb.append("'. However, the class '");
-            sb.append(name);
-            sb.append("' is available from the system class loader. There are two fixes: 1) Add package '");
-            sb.append(pkgName);
-            sb.append("' to the '");
-            sb.append(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
-            sb.append("' property and modify bundle ");
-            sb.append(importer);
-            sb.append(" to import this package; this causes the system bundle to export class path packages. 2) Add package '");
-            sb.append(pkgName);
-            sb.append("' to the '");
-            sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
-            sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
-            sb.append(" ***");
-
-            return sb.toString();
-        }
-        catch (Exception ex2)
-        {
-        }
-
-        // Finally, if there are no imports or exports for the package
-        // and it is not available on the system class path, simply
-        // log a message saying so.
-        StringBuffer sb = new StringBuffer("*** Class '");
-        sb.append(name);
-        sb.append("' was not found. Bundle ");
-        sb.append(importer);
-        sb.append(" does not import package '");
-        sb.append(pkgName);
-        sb.append("', nor is the package exported by any other bundle or available from the system class loader.");
-        sb.append(" ***");
-
-        return sb.toString();
-    }
 }
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
new file mode 100644
index 0000000..db4c8cd
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -0,0 +1,2235 @@
+/*
+ * 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.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+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;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+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.StatefulResolver;
+import org.apache.felix.framework.cache.JarContent;
+import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.resolver.HostedCapability;
+import org.apache.felix.framework.resolver.HostedRequirement;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.ResolverWire;
+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;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+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.BundleException;
+import org.osgi.framework.BundleReference;
+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;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class BundleWiringImpl implements BundleWiring
+{
+    public final static int EAGER_ACTIVATION = 0;
+    public final static int LAZY_ACTIVATION = 1;
+
+    private final Logger m_logger;
+    private final Map m_configMap;
+    private final StatefulResolver m_resolver;
+    private final BundleRevisionImpl m_revision;
+    private final List<BundleRevision> m_fragments;
+    private final List<BundleWire> m_wires;
+    private final Map<String, BundleRevision> m_importedPkgs;
+    private final Map<String, List<BundleRevision>> m_requiredPkgs;
+    private final List<BundleCapability> m_resolvedCaps;
+    private final List<BundleRequirement> m_resolvedReqs;
+    private final List<BundleRequirement> m_resolvedDynamicReqs;
+    private final List<R4Library> m_resolvedNativeLibs;
+    private final Content[] m_contentPath;
+    private final Content[] m_fragmentContents;
+
+    private BundleClassLoader m_classLoader;
+    private boolean m_isActivationTriggered = false;
+    private ProtectionDomain m_protectionDomain = null;
+    private final static SecureAction m_secureAction = new SecureAction();
+
+    // Bundle-specific class loader for boot delegation.
+    private final ClassLoader m_bootClassLoader;
+    // Default class loader for boot delegation.
+    private final static ClassLoader m_defBootClassLoader;
+
+    // Statically define the default class loader for boot delegation.
+    static
+    {
+        ClassLoader cl = null;
+        try
+        {
+            Constructor ctor = m_secureAction.getDeclaredConstructor(
+                SecureClassLoader.class, new Class[] { ClassLoader.class });
+            m_secureAction.setAccesssible(ctor);
+            cl = (ClassLoader) m_secureAction.invoke(ctor, new Object[] { null });
+        }
+        catch (Throwable ex)
+        {
+            // On Android we get an exception if we set the parent class loader
+            // to null, so we will work around that case by setting the parent
+            // class loader to the system class loader in getClassLoader() below.
+            cl = null;
+            System.err.println("Problem creating boot delegation class loader: " + ex);
+        }
+        m_defBootClassLoader = cl;
+    }
+
+    // Boolean flag to enable/disable implicit boot delegation.
+    private final boolean m_implicitBootDelegation;
+    // Boolean flag to enable/disable local URLs.
+    private final boolean m_useLocalURLs;
+
+    // Re-usable security manager for accessing class context.
+    private static SecurityManagerEx m_sm = new SecurityManagerEx();
+
+    // Thread local to detect class loading cycles.
+    private final ThreadLocal m_cycleCheck = new ThreadLocal();
+
+    // Thread local to keep track of deferred activation.
+    private static final ThreadLocal m_deferredActivation = new ThreadLocal();
+
+    // Flag indicating whether we are on an old JVM or not.
+    private volatile static boolean m_isPreJava5 = false;
+
+    BundleWiringImpl(
+        Logger logger, Map configMap, StatefulResolver resolver,
+        BundleRevisionImpl revision, List<BundleRevision> fragments,
+        List<ResolverWire> resolverWires,
+        Map<ResolverWire, Set<String>> requiredPkgWires)
+        throws Exception
+    {
+        m_logger = logger;
+        m_configMap = configMap;
+        m_resolver = resolver;
+        m_revision = revision;
+
+        List<BundleWire> wires = new ArrayList<BundleWire>(resolverWires.size());
+        Map<String, BundleRevision> importedPkgs =
+            new HashMap<String, BundleRevision>();
+        Map<String, List<BundleRevision>> requiredPkgs =
+            new HashMap<String, List<BundleRevision>>();
+
+        for (ResolverWire rw : resolverWires)
+        {
+            wires.add(
+                new BundleWireImpl(
+                    rw.getRequirer(),
+                    rw.getRequirement(),
+                    rw.getProvider(),
+                    rw.getCapability()));
+
+            if (Util.isFragment(m_revision))
+            {
+                m_logger.log(
+                    Logger.LOG_DEBUG,
+                    "FRAGMENT WIRE: "
+                    + this + " -> hosted by -> " + rw.getProvider());
+            }
+            else
+            {
+                m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
+
+                if (rw.getCapability().getNamespace()
+                    .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                {
+                    ((BundleRevisionImpl) rw.getProvider()).addDependentImporter(m_revision);
+
+                    importedPkgs.put(
+                        (String) rw.getCapability().getAttributes()
+                            .get(BundleCapabilityImpl.PACKAGE_ATTR),
+                        rw.getProvider());
+                }
+                else if (rw.getCapability().getNamespace()
+                    .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                {
+                    ((BundleRevisionImpl) rw.getProvider()).addDependentRequirer(m_revision);
+
+                    for (String pkgName : requiredPkgWires.get(rw))
+                    {
+                        List<BundleRevision> revs = requiredPkgs.get(pkgName);
+                        if (revs != null)
+                        {
+                            revs.add(rw.getProvider());
+                        }
+                        else
+                        {
+                            revs = new ArrayList<BundleRevision>();
+                            revs.add(rw.getProvider());
+                            requiredPkgs.put(pkgName, revs);
+                        }
+                    }
+                }
+            }
+        }
+        m_wires = wires;
+        m_requiredPkgs = requiredPkgs;
+        m_importedPkgs = importedPkgs;
+
+        // 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.
+        Content[] fragmentContents = null;
+        if (fragments != null)
+        {
+            // 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 (fragments.size() > 1)
+            {
+                SortedMap<String, BundleRevision> sorted = new TreeMap<String, BundleRevision>();
+                for (BundleRevision f : fragments)
+                {
+                    sorted.put(((BundleRevisionImpl) f).getId(), f);
+                }
+                fragments = new ArrayList(sorted.values());
+            }
+            fragmentContents = new Content[fragments.size()];
+            for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
+            {
+                fragmentContents[i] =
+                    ((BundleRevisionImpl) fragments.get(i)).getContent()
+                        .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
+            }
+        }
+        m_fragments = fragments;
+        m_fragmentContents = fragmentContents;
+
+        // Recalculate the content path for the new fragments.
+        m_contentPath = initializeContentPath();
+
+        List<BundleCapability> capList = (m_revision.getDeclaredCapabilities(null) == null)
+            ? new ArrayList<BundleCapability>()
+            : new ArrayList<BundleCapability>(m_revision.getDeclaredCapabilities(null));
+        for (int fragIdx = 0;
+            (m_fragments != null) && (fragIdx < m_fragments.size());
+            fragIdx++)
+        {
+            List<BundleCapability> caps =
+                m_fragments.get(fragIdx).getDeclaredCapabilities(null);
+            for (int capIdx = 0;
+                (caps != null) && (capIdx < caps.size());
+                capIdx++)
+            {
+                if (caps.get(capIdx).getNamespace().equals(
+                    BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                {
+                    capList.add(
+                        new HostedCapability(
+                            m_revision, (BundleCapabilityImpl) caps.get(capIdx)));
+                }
+            }
+        }
+        m_resolvedCaps = Collections.unmodifiableList(capList);
+
+        List<BundleRequirement> reqList = (m_revision.getDeclaredRequirements(null) == null)
+            ? new ArrayList() : new ArrayList(m_revision.getDeclaredRequirements(null));
+        for (int fragIdx = 0;
+            (m_fragments != null) && (fragIdx < m_fragments.size());
+            fragIdx++)
+        {
+            List<BundleRequirement> reqs =
+                m_fragments.get(fragIdx).getDeclaredRequirements(null);
+            for (int reqIdx = 0;
+                (reqs != null) && (reqIdx < reqs.size());
+                reqIdx++)
+            {
+                if (reqs.get(reqIdx).getNamespace().equals(
+                        BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                    || reqs.get(reqIdx).getNamespace().equals(
+                        BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                {
+                    reqList.add(
+                        new HostedRequirement(
+                            m_revision, (BundleRequirementImpl) reqs.get(reqIdx)));
+                }
+            }
+        }
+        m_resolvedReqs = Collections.unmodifiableList(reqList);
+
+        List<BundleRequirement> dynReqList = (m_revision.getDeclaredDynamicRequirements() == null)
+            ? new ArrayList()
+            : new ArrayList(m_revision.getDeclaredDynamicRequirements());
+        for (int fragIdx = 0;
+            (m_fragments != null) && (fragIdx < m_fragments.size());
+            fragIdx++)
+        {
+            List<BundleRequirement> reqs =
+                ((BundleRevisionImpl) m_fragments.get(fragIdx))
+                    .getDeclaredDynamicRequirements();
+            for (int reqIdx = 0;
+                (reqs != null) && (reqIdx < reqs.size());
+                reqIdx++)
+            {
+                if (reqs.get(reqIdx).getNamespace().equals(
+                    BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                {
+                    dynReqList.add(reqs.get(reqIdx));
+                }
+            }
+        }
+        m_resolvedDynamicReqs = Collections.unmodifiableList(dynReqList);
+
+        List<R4Library> libList = (m_revision.getDeclaredNativeLibraries() == null)
+            ? new ArrayList<R4Library>()
+            : new ArrayList<R4Library>(m_revision.getDeclaredNativeLibraries());
+        for (int fragIdx = 0;
+            (m_fragments != null) && (fragIdx < m_fragments.size());
+            fragIdx++)
+        {
+            List<R4Library> libs =
+                ((BundleRevisionImpl) m_fragments.get(fragIdx))
+                    .getDeclaredNativeLibraries();
+            for (int reqIdx = 0;
+                (libs != null) && (reqIdx < libs.size());
+                reqIdx++)
+            {
+                libList.add(libs.get(reqIdx));
+            }
+        }
+        // We need to return null here if we don't have any libraries, since a
+        // zero-length array is used to indicate that matching native libraries
+        // could not be found when resolving the bundle.
+        m_resolvedNativeLibs = (libList.isEmpty())
+            ? null
+            : Collections.unmodifiableList(libList);
+
+        ClassLoader bootLoader = m_defBootClassLoader;
+        if (revision.getBundle().getBundleId() != 0)
+        {
+            Object map = m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
+            if (map instanceof Map)
+            {
+                Object l = ((Map) map).get(m_revision.getBundle());
+                if (l instanceof ClassLoader)
+                {
+                    bootLoader = (ClassLoader) l;
+                }
+            }
+        }
+        m_bootClassLoader = bootLoader;
+
+        m_implicitBootDelegation =
+            (m_configMap.get(FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP) == null)
+            || Boolean.valueOf(
+                (String) m_configMap.get(
+                    FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP)).booleanValue();
+
+        m_useLocalURLs =
+            (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
+                ? false : true;
+    }
+
+    public void dispose()
+    {
+        if (!Util.isFragment(m_revision) && (m_wires != null))
+        {
+            for (BundleWire bw : m_wires)
+            {
+                if (bw.getProviderWiring() != null)
+                {
+                    if (bw.getCapability().getNamespace()
+                        .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                    {
+                        ((BundleRevisionImpl) bw.getProviderWiring().getRevision())
+                            .removeDependentImporter(m_revision);
+                    }
+                    else if (bw.getCapability().getNamespace()
+                        .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                    {
+                        ((BundleRevisionImpl) bw.getProviderWiring().getRevision())
+                            .removeDependentRequirer(m_revision);
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; (m_contentPath != null) && (i < m_contentPath.length); i++)
+        {
+            m_contentPath[i].close();
+        }
+        for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+        {
+            m_fragmentContents[i].close();
+        }
+        m_classLoader = null;
+    }
+
+    private Content[] initializeContentPath() throws Exception
+    {
+        List contentList = new ArrayList();
+        calculateContentPath(m_revision, m_revision.getContent(), contentList, true);
+        for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+        {
+            calculateContentPath(m_fragments.get(i), m_fragmentContents[i], contentList, false);
+        }
+        return (Content[]) contentList.toArray(new Content[contentList.size()]);
+    }
+
+    private List calculateContentPath(
+        BundleRevision revision, Content content, List contentList, boolean searchFragments)
+        throws Exception
+    {
+        // Creating the content path entails examining the bundle's
+        // class path to determine whether the bundle JAR file itself
+        // is on the bundle's class path and then creating content
+        // objects for everything on the class path.
+
+        // Create a list to contain the content path for the specified content.
+        List localContentList = new ArrayList();
+
+        // Find class path meta-data.
+        String classPath = (String) ((BundleRevisionImpl) revision)
+            .getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
+        // Parse the class path into strings.
+        List<String> classPathStrings = ManifestParser.parseDelimitedString(
+            classPath, FelixConstants.CLASS_PATH_SEPARATOR);
+
+        if (classPathStrings == null)
+        {
+            classPathStrings = new ArrayList<String>(0);
+        }
+
+        // Create the bundles class path.
+        for (int i = 0; i < classPathStrings.size(); i++)
+        {
+            // Remove any leading slash, since all bundle class path
+            // entries are relative to the root of the bundle.
+            classPathStrings.set(i, (classPathStrings.get(i).startsWith("/"))
+                ? classPathStrings.get(i).substring(1)
+                : classPathStrings.get(i));
+
+            // Check for the bundle itself on the class path.
+            if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT))
+            {
+                localContentList.add(content);
+            }
+            else
+            {
+                // Try to find the embedded class path entry in the current
+                // content.
+                Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
+                // If the embedded class path entry was not found, it might be
+                // in one of the fragments if the current content is the bundle,
+                // so try to search the fragments if necessary.
+                for (int fragIdx = 0;
+                    searchFragments && (embeddedContent == null)
+                        && (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
+                    fragIdx++)
+                {
+                    embeddedContent =
+                        m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings.get(i));
+                }
+                // If we found the embedded content, then add it to the
+                // class path content list.
+                if (embeddedContent != null)
+                {
+                    localContentList.add(embeddedContent);
+                }
+                else
+                {
+// TODO: FRAMEWORK - Per the spec, this should fire a FrameworkEvent.INFO event;
+//       need to create an "Eventer" class like "Logger" perhaps.
+                    m_logger.log(m_revision.getBundle(), Logger.LOG_INFO,
+                        "Class path entry not found: "
+                        + classPathStrings.get(i));
+                }
+            }
+        }
+
+        // If there is nothing on the class path, then include
+        // "." by default, as per the spec.
+        if (localContentList.isEmpty())
+        {
+            localContentList.add(content);
+        }
+
+        // Now add the local contents to the global content list and return it.
+        contentList.addAll(localContentList);
+        return contentList;
+    }
+
+// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
+//       resolver to determine if a bundle can dynamically import.
+    public synchronized boolean hasPackageSource(String pkgName)
+    {
+        return (m_importedPkgs.containsKey(pkgName) || m_requiredPkgs.containsKey(pkgName));
+    }
+
+// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
+//       to implement dynamic imports.
+    public synchronized BundleRevision getImportedPackageSource(String pkgName)
+    {
+        return m_importedPkgs.get(pkgName);
+    }
+
+    public List<BundleRevision> getFragments()
+    {
+        return m_fragments;
+    }
+
+    public boolean isCurrent()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean isInUse()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<BundleCapability> getCapabilities(String namespace)
+    {
+        List<BundleCapability> result = m_resolvedCaps;
+        if (namespace != null)
+        {
+            result = new ArrayList<BundleCapability>();
+            for (BundleCapability cap : m_resolvedCaps)
+            {
+                if (cap.getNamespace().equals(namespace))
+                {
+                    result.add(cap);
+                }
+            }
+        }
+        return result;
+    }
+
+    public List<BundleRequirement> getRequirements(String namespace)
+    {
+
+        List<BundleRequirement> result = m_resolvedReqs;
+        if (namespace != null)
+        {
+            result = new ArrayList<BundleRequirement>();
+            for (BundleRequirement req : m_resolvedReqs)
+            {
+                if (req.getNamespace().equals(namespace))
+                {
+                    result.add(req);
+                }
+            }
+        }
+        return result;
+    }
+
+    public List<BundleRequirement> getDynamicRequirements()
+    {
+        return m_resolvedDynamicReqs;
+    }
+
+    public List<R4Library> getNativeLibraries()
+    {
+        return m_resolvedNativeLibs;
+    }
+
+    public List<BundleWire> getProvidedWires(String namespace)
+    {
+// TODO: OSGI R4.3 - IMPLEMENT THIS!!
+        return Collections.EMPTY_LIST;
+    }
+
+    public List<BundleWire> getRequiredWires(String namespace)
+    {
+        return m_wires;
+    }
+
+    public synchronized void addDynamicWire(ResolverWire rw)
+    {
+        // 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.
+
+        BundleWire wire = new BundleWireImpl(
+            rw.getRequirer(),
+            rw.getRequirement(),
+            rw.getProvider(),
+            rw.getCapability());
+        m_wires.add(wire);
+        m_importedPkgs.put(
+            (String) wire.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
+            rw.getProvider());
+    }
+
+    public BundleRevision getRevision()
+    {
+        return m_revision;
+    }
+
+    public synchronized ClassLoader getClassLoader()
+    {
+        if (m_classLoader == null)
+        {
+            // Determine which class loader to use based on which
+            // Java platform we are running on.
+            Class clazz;
+            if (m_isPreJava5)
+            {
+                clazz = BundleClassLoader.class;
+            }
+            else
+            {
+                try
+                {
+                    clazz = BundleClassLoaderJava5.class;
+                }
+                catch (Throwable th)
+                {
+                    // If we are on pre-Java5 then we will get a verify error
+                    // here since we try to override a getResources() which is
+                    // a final method in pre-Java5.
+                    m_isPreJava5 = true;
+                    clazz = BundleClassLoader.class;
+                }
+            }
+
+            // Use SecureAction to create the class loader if security is
+            // enabled; otherwise, create it directly.
+            try
+            {
+                Constructor ctor = (Constructor) m_secureAction.getConstructor(
+                    clazz, new Class[] { BundleWiringImpl.class, ClassLoader.class });
+                m_classLoader = (BundleClassLoader)
+                    m_secureAction.invoke(ctor,
+                    new Object[] { this, determineParentClassLoader() });
+            }
+            catch (Exception ex)
+            {
+                throw new RuntimeException("Unable to create module class loader: "
+                    + ex.getMessage() + " [" + ex.getClass().getName() + "]");
+            }
+        }
+        return m_classLoader;
+    }
+
+    public List<URL> findEntries(String path, String filePattern, int options)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Collection<String> listResources(String path, String filePattern, int options)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public Bundle getBundle()
+    {
+        return m_revision.getBundle();
+    }
+
+    //
+    // Class loader implementation methods.
+    //
+
+    public URL getLocalURL(int index, String urlPath)
+    {
+        if (urlPath.startsWith("/"))
+        {
+            urlPath = urlPath.substring(1);
+        }
+        if (index == 0)
+        {
+            return m_revision.getContent().getEntryAsURL(urlPath);
+        }
+        return m_contentPath[index - 1].getEntryAsURL(urlPath);
+    }
+
+    private URL createURL(int port, String path)
+    {
+        // Add a slash if there is one already, otherwise
+        // the is no slash separating the host from the file
+        // in the resulting URL.
+        if (!path.startsWith("/"))
+        {
+            path = "/" + path;
+        }
+
+        try
+        {
+            return m_secureAction.createURL(null,
+                FelixConstants.BUNDLE_URL_PROTOCOL + "://" +
+                m_revision.getId() + ":" + port + path, m_revision.getURLStreamHandler());
+        }
+        catch (MalformedURLException ex)
+        {
+            m_logger.log(m_revision.getBundle(),
+                Logger.LOG_ERROR,
+                "Unable to create resource URL.",
+                ex);
+        }
+        return null;
+    }
+
+    URL getResourceLocal(String name)
+    {
+        URL url = null;
+
+        // Remove leading slash, if present, but special case
+        // "/" so that it returns a root URL...this isn't very
+        // clean or meaninful, but the Spring guys want it.
+        if (name.equals("/"))
+        {
+            // Just pick a class path index since it doesn't really matter.
+            url = createURL(1, name);
+        }
+        else if (name.startsWith("/"))
+        {
+            name = name.substring(1);
+        }
+
+        // Check the module class path.
+        for (int i = 0;
+            (url == null) &&
+            (i < m_contentPath.length); i++)
+        {
+            if (m_contentPath[i].hasEntry(name))
+            {
+                url = createURL(i + 1, name);
+            }
+        }
+
+        return url;
+    }
+
+    public Enumeration getResourcesByDelegation(String name)
+    {
+        Set requestSet = (Set) m_cycleCheck.get();
+        if (requestSet == null)
+        {
+            requestSet = new HashSet();
+            m_cycleCheck.set(requestSet);
+        }
+        if (!requestSet.contains(name))
+        {
+            requestSet.add(name);
+            try
+            {
+                return findResourcesByDelegation(name);
+            }
+            finally
+            {
+                requestSet.remove(name);
+            }
+        }
+
+        return null;
+    }
+
+    private Enumeration findResourcesByDelegation(String name)
+    {
+        Enumeration urls = null;
+        List completeUrlList = new ArrayList();
+
+        // First, try to resolve the originating module.
+        try
+        {
+            m_resolver.resolve(m_revision);
+        }
+        catch (ResolveException ex)
+        {
+            // The spec states that if the bundle cannot be resolved, then
+            // only the local bundle's resources should be searched. So we
+            // will ask the module's own class path.
+            return getResourcesLocal(name);
+        }
+
+        // Get the package of the target class/resource.
+        String pkgName = Util.getResourcePackage(name);
+
+        // Delegate any packages listed in the boot delegation
+        // property to the parent class loader.
+        if (shouldBootDelegate(pkgName))
+        {
+            try
+            {
+                // Get the appropriate class loader for delegation.
+                ClassLoader bdcl = getBootDelegationClassLoader();
+                urls = bdcl.getResources(name);
+            }
+            catch (IOException ex)
+            {
+                // This shouldn't happen and even if it does, there
+                // is nothing we can do, so just ignore it.
+            }
+            // If this is a java.* package, then always terminate the
+            // search; otherwise, continue to look locally.
+            if (pkgName.startsWith("java."))
+            {
+                return urls;
+            }
+
+            completeUrlList.add(urls);
+        }
+
+        // Look in the revisions's imported packages. If the package is
+        // imported, then we stop searching no matter the result since
+        // imported packages cannot be split.
+        BundleRevision provider = m_importedPkgs.get(pkgName);
+        if (provider != null)
+        {
+            // Delegate to the provider revision.
+            urls = ((BundleWiringImpl) provider.getWiring()).getResourcesByDelegation(name);
+
+            // If we find any resources, then add them.
+            if ((urls != null) && (urls.hasMoreElements()))
+            {
+                completeUrlList.add(urls);
+            }
+
+            // Always return here since imported packages cannot be split
+            // across required bundles or the revision's content.
+            return new CompoundEnumeration((Enumeration[])
+                completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
+        }
+
+        // See whether we can get the resource from the required bundles and
+        // regardless of whether or not this is the case continue to the next
+        // step potentially passing on the result of this search (if any).
+        List<BundleRevision> providers = m_requiredPkgs.get(pkgName);
+        if (providers != null)
+        {
+            for (BundleRevision p : providers)
+            {
+                // Delegate to the provider revision.
+                urls = ((BundleWiringImpl) p.getWiring()).getResourcesByDelegation(name);
+
+                // If we find any resources, then add them.
+                if ((urls != null) && (urls.hasMoreElements()))
+                {
+                    completeUrlList.add(urls);
+                }
+
+                // Do not return here, since required packages can be split
+                // across the revision's content.
+            }
+        }
+
+        // Try the module's own class path. If we can find the resource then
+        // return it together with the results from the other searches else
+        // try to look into the dynamic imports.
+        urls = getResourcesLocal(name);
+        if ((urls != null) && (urls.hasMoreElements()))
+        {
+            completeUrlList.add(urls);
+        }
+        else
+        {
+            // If not found, then try the module's dynamic imports.
+            // At this point, the module's imports were searched and so was the
+            // the module's content. Now we make an attempt to load the
+            // class/resource via a dynamic import, if possible.
+            try
+            {
+                provider = m_resolver.resolve(m_revision, pkgName);
+            }
+            catch (ResolveException ex)
+            {
+                // Ignore this since it is likely normal.
+            }
+            if (provider != null)
+            {
+                // Delegate to the provider revision.
+                urls = ((BundleWiringImpl) provider.getWiring()).getResourcesByDelegation(name);
+
+                // If we find any resources, then add them.
+                if ((urls != null) && (urls.hasMoreElements()))
+                {
+                    completeUrlList.add(urls);
+                }
+            }
+        }
+
+        return new CompoundEnumeration((Enumeration[])
+            completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
+    }
+
+    private Enumeration getResourcesLocal(String name)
+    {
+        List l = new ArrayList();
+
+        // Special case "/" so that it returns a root URLs for
+        // each bundle class path entry...this isn't very
+        // clean or meaningful, but the Spring guys want it.
+        if (name.equals("/"))
+        {
+            for (int i = 0; i < m_contentPath.length; i++)
+            {
+                l.add(createURL(i + 1, name));
+            }
+        }
+        else
+        {
+            // Remove leading slash, if present.
+            if (name.startsWith("/"))
+            {
+                name = name.substring(1);
+            }
+
+            // Check the module class path.
+            for (int i = 0; i < m_contentPath.length; i++)
+            {
+                if (m_contentPath[i].hasEntry(name))
+                {
+                    // Use the class path index + 1 for creating the path so
+                    // that we can differentiate between module content URLs
+                    // (where the path will start with 0) and module class
+                    // path URLs.
+                    l.add(createURL(i + 1, name));
+                }
+            }
+        }
+
+        return Collections.enumeration(l);
+    }
+
+    private ClassLoader determineParentClassLoader()
+    {
+        // Determine the class loader's parent based on the
+        // configuration property; use boot class loader by
+        // default.
+        String cfg = (String) m_configMap.get(Constants.FRAMEWORK_BUNDLE_PARENT);
+        cfg = (cfg == null) ? Constants.FRAMEWORK_BUNDLE_PARENT_BOOT : cfg;
+        final ClassLoader parent;
+        if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_APP))
+        {
+            parent = m_secureAction.getSystemClassLoader();
+        }
+        else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_EXT))
+        {
+            parent = m_secureAction.getParentClassLoader(m_secureAction.getSystemClassLoader());
+        }
+        else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK))
+        {
+            parent = m_secureAction.getClassLoader(BundleRevisionImpl.class);
+        }
+        // On Android we cannot set the parent class loader to be null, so
+        // we special case that situation here and set it to the system
+        // class loader by default instead, which is not really spec.
+        else if (m_bootClassLoader == null)
+        {
+            parent = m_secureAction.getSystemClassLoader();
+        }
+        else
+        {
+            parent = null;
+        }
+        return parent;
+    }
+
+    boolean shouldBootDelegate(String pkgName)
+    {
+        // Always boot delegate if the bundle has a configured
+        // boot class loader.
+        if (m_bootClassLoader != m_defBootClassLoader)
+        {
+            return true;
+        }
+
+        boolean result = false;
+
+        // Only consider delegation if we have a package name, since
+        // we don't want to promote the default package. The spec does
+        // not take a stand on this issue.
+        if (pkgName.length() > 0)
+        {
+            for (int i = 0; !result && (i < m_revision.getBootDelegationPackages().length); i++)
+            {
+                // Check if the boot package is wildcarded.
+                // A wildcarded boot package will be in the form "foo.",
+                // so a matching subpackage will start with "foo.", e.g.,
+                // "foo.bar".
+                if (m_revision.getBootDelegationPackageWildcards()[i]
+                    && pkgName.startsWith(m_revision.getBootDelegationPackages()[i]))
+                {
+                    return true;
+                }
+                // If not wildcarded, then check for an exact match.
+                else if (m_revision.getBootDelegationPackages()[i].equals(pkgName))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    ClassLoader getBootDelegationClassLoader()
+    {
+        // Get the appropriate class loader for delegation.
+        ClassLoader parent = (m_classLoader == null)
+            ? determineParentClassLoader() : m_classLoader.getParent();
+        return (parent == null) ? m_bootClassLoader : parent;
+    }
+
+    private static final Constructor m_dexFileClassConstructor;
+    private static final Method m_dexFileClassLoadDex;
+    private static final Method m_dexFileClassLoadClass;
+
+    static
+    {
+        Constructor dexFileClassConstructor = null;
+        Method dexFileClassLoadDex = null;
+        Method dexFileClassLoadClass = null;
+        try
+        {
+            Class dexFileClass;
+            try
+            {
+                dexFileClass = Class.forName("dalvik.system.DexFile");
+            }
+            catch (Exception ex)
+            {
+                dexFileClass = Class.forName("android.dalvik.DexFile");
+            }
+
+            try
+            {
+                dexFileClassLoadDex = dexFileClass.getMethod("loadDex", 
+                    new Class[]{String.class, String.class, Integer.TYPE});
+            }
+            catch (Exception ex)
+            {
+                // Nothing we need to do 
+            }
+            dexFileClassConstructor = dexFileClass.getConstructor(
+                new Class[] { java.io.File.class });
+            dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
+                new Class[] { String.class, ClassLoader.class });
+        }
+        catch (Throwable ex)
+        {
+           dexFileClassConstructor = null;
+           dexFileClassLoadDex = null;
+           dexFileClassLoadClass = null;
+        }
+        m_dexFileClassConstructor = dexFileClassConstructor;
+        m_dexFileClassLoadDex= dexFileClassLoadDex;
+        m_dexFileClassLoadClass = dexFileClassLoadClass;
+    }
+
+    public Class getClassByDelegation(String name) throws ClassNotFoundException
+    {
+        // We do not call getClassLoader().loadClass() for arrays because
+        // it does not correctly handle array types, which is necessary in
+        // cases like deserialization using a wrapper class loader.
+        if ((name != null) && (name.length() > 0) && (name.charAt(0) == '['))
+        {
+            return Class.forName(name, false, getClassLoader());
+        }
+        return getClassLoader().loadClass(name);
+    }
+
+    public URL getResourceByDelegation(String name)
+    {
+        try
+        {
+            return (URL) findClassOrResourceByDelegation(name, false);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            // This should never be thrown because we are loading resources.
+        }
+        catch (ResourceNotFoundException ex)
+        {
+            m_logger.log(m_revision.getBundle(),
+                Logger.LOG_DEBUG,
+                ex.getMessage());
+        }
+        return null;
+    }
+
+    private Object findClassOrResourceByDelegation(String name, boolean isClass)
+        throws ClassNotFoundException, ResourceNotFoundException
+    {
+        Object result = null;
+
+        Set requestSet = (Set) m_cycleCheck.get();
+        if (requestSet == null)
+        {
+            requestSet = new HashSet();
+            m_cycleCheck.set(requestSet);
+        }
+        if (requestSet.add(name))
+        {
+            try
+            {
+                // First, try to resolve the originating revision.
+                m_resolver.resolve(m_revision);
+
+                // Get the package of the target class/resource.
+                String pkgName = (isClass)
+                    ? Util.getClassPackage(name)
+                    : Util.getResourcePackage(name);
+
+                // Delegate any packages listed in the boot delegation
+                // property to the parent class loader.
+                if (shouldBootDelegate(pkgName))
+                {
+                    try
+                    {
+                        // Get the appropriate class loader for delegation.
+                        ClassLoader bdcl = getBootDelegationClassLoader();
+                        result = (isClass)
+                            ? (Object) bdcl.loadClass(name)
+                            : (Object) bdcl.getResource(name);
+                        // If this is a java.* package, then always terminate the
+                        // search; otherwise, continue to look locally if not found.
+                        if (pkgName.startsWith("java.") || (result != null))
+                        {
+                            return result;
+                        }
+                    }
+                    catch (ClassNotFoundException ex)
+                    {
+                        // If this is a java.* package, then always terminate the
+                        // search; otherwise, continue to look locally if not found.
+                        if (pkgName.startsWith("java."))
+                        {
+                            throw ex;
+                        }
+                    }
+                }
+
+                // Look in the revision's imports. Note that the search may
+                // be aborted if this method throws an exception, otherwise
+                // it continues if a null is returned.
+                result = searchImports(pkgName, name, isClass);
+
+                // If not found, try the revision's own class path.
+                if (result == null)
+                {
+                    result = (isClass)
+                        ? (Object) ((BundleClassLoader) getClassLoader()).findClass(name)
+                        : (Object) getResourceLocal(name);
+
+                    // If still not found, then try the revision's dynamic imports.
+                    if (result == null)
+                    {
+                        result = searchDynamicImports(pkgName, name, isClass);
+                    }
+                }
+            }
+            catch (ResolveException ex)
+            {
+                if (isClass)
+                {
+                    // We do not use the resolve exception as the
+                    // cause of the exception, since this would
+                    // potentially leak internal module information.
+                    throw new ClassNotFoundException(
+                        name + " not found because "
+                        + getBundle()
+                        + " cannot resolve: "
+                        + ex.getRequirement());
+                }
+                else
+                {
+                    // The spec states that if the bundle cannot be resolved, then
+                    // only the local bundle's resources should be searched. So we
+                    // will ask the module's own class path.
+                    URL url = getResourceLocal(name);
+                    if (url != null)
+                    {
+                        return url;
+                    }
+
+                    // We need to throw a resource not found exception.
+                    throw new ResourceNotFoundException(
+                        name + " not found because "
+                        + getBundle()
+                        + " cannot resolve: "
+                        + ex.getRequirement());
+                }
+            }
+            finally
+            {
+                requestSet.remove(name);
+            }
+        }
+        else
+        {
+            // If a cycle is detected, we should return null to break the
+            // cycle. This should only ever be return to internal class
+            // loading code and not to the actual instigator of the class load.
+            return null;
+        }
+
+        if (result == null)
+        {
+            if (isClass)
+            {
+                throw new ClassNotFoundException(
+                    name + " not found by " + this.getBundle());
+            }
+            else
+            {
+                throw new ResourceNotFoundException(
+                    name + " not found by " + this.getBundle());
+            }
+        }
+
+        return result;
+    }
+
+    private Object searchImports(String pkgName, String name, boolean isClass)
+        throws ClassNotFoundException, ResourceNotFoundException
+    {
+        // Check if the package is imported.
+        BundleRevision provider = m_importedPkgs.get(pkgName);
+        if (provider != null)
+        {
+            // If we find the class or resource, then return it.
+            Object result = (isClass)
+                ? (Object) ((BundleWiringImpl) provider.getWiring()).getClassByDelegation(name)
+                : (Object) ((BundleWiringImpl) provider.getWiring()).getResourceByDelegation(name);
+            if (result != null)
+            {
+                return result;
+            }
+
+            // If no class was found, then we must throw an exception
+            // since the provider of this package did not contain the
+            // requested class and imported packages are atomic.
+            throw new ClassNotFoundException(name);
+        }
+
+        // Check if the package is required.
+        List<BundleRevision> providers = m_requiredPkgs.get(pkgName);
+        if (providers != null)
+        {
+            for (BundleRevision p : providers)
+            {
+                // If we find the class or resource, then return it.
+                try
+                {
+                    Object result = (isClass)
+                        ? (Object) ((BundleWiringImpl) p.getWiring()).getClassByDelegation(name)
+                        : (Object) ((BundleWiringImpl) p.getWiring()).getResourceByDelegation(name);
+                    if (result != null)
+                    {
+                        return result;
+                    }
+                }
+                catch (ClassNotFoundException ex)
+                {
+                    // Since required packages can be split, don't throw an
+                    // exception here if it is not found. Instead, we'll just
+                    // continue searching other required bundles and the
+                    // revision's local content.
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private Object searchDynamicImports(
+        final String pkgName, final String name, final boolean isClass)
+        throws ClassNotFoundException, ResourceNotFoundException
+    {
+        // At this point, the module's imports were searched and so was the
+        // the module's content. Now we make an attempt to load the
+        // class/resource via a dynamic import, if possible.
+        BundleRevision provider = null;
+        try
+        {
+            provider = m_resolver.resolve(m_revision, pkgName);
+        }
+        catch (ResolveException ex)
+        {
+            // Ignore this since it is likely normal.
+        }
+
+        // If the dynamic import was successful, then this initial
+        // time we must directly return the result from dynamically
+        // created package sources, but subsequent requests for
+        // classes/resources in the associated package will be
+        // processed as part of normal static imports.
+        if (provider != null)
+        {
+            // Return the class or resource.
+            return (isClass)
+                ? (Object) ((BundleWiringImpl) provider.getWiring()).getClassByDelegation(name)
+                : (Object) ((BundleWiringImpl) provider.getWiring()).getResourceByDelegation(name);
+        }
+
+        // If implicit boot delegation is enabled, then try to guess whether
+        // we should boot delegate.
+        if (m_implicitBootDelegation)
+        {
+            // At this point, the class/resource could not be found by the bundle's
+            // static or dynamic imports, nor its own content. Before we throw
+            // an exception, we will try to determine if the instigator of the
+            // class/resource load was a class from a bundle or not. This is necessary
+            // because the specification mandates that classes on the class path
+            // should be hidden (except for java.*), but it does allow for these
+            // classes/resources to be exposed by the system bundle as an export.
+            // However, in some situations classes on the class path make the faulty
+            // assumption that they can access everything on the class path from
+            // every other class loader that they come in contact with. This is
+            // not true if the class loader in question is from a bundle. Thus,
+            // this code tries to detect that situation. If the class instigating
+            // the load request was NOT from a bundle, then we will make the
+            // assumption that the caller actually wanted to use the parent class
+            // loader and we will delegate to it. If the class was
+            // from a bundle, then we will enforce strict class loading rules
+            // for the bundle and throw an exception.
+
+            // Get the class context to see the classes on the stack.
+            final Class[] classes = m_sm.getClassContext();
+            try
+            {
+                if (System.getSecurityManager() != null)
+                {
+                    return AccessController
+                        .doPrivileged(new PrivilegedExceptionAction()
+                        {
+                            public Object run() throws Exception
+                            {
+                                return doImplicitBootDelegation(classes, name,
+                                    isClass);
+                            }
+                        });
+                }
+                else
+                {
+                    return doImplicitBootDelegation(classes, name, isClass);
+                }
+            }
+            catch (PrivilegedActionException ex)
+            {
+                Exception cause = ex.getException();
+                if (cause instanceof ClassNotFoundException)
+                {
+                    throw (ClassNotFoundException) cause;
+                }
+                else
+                {
+                    throw (ResourceNotFoundException) cause;
+                }
+            }
+        }
+        return null;
+    }
+
+    private Object doImplicitBootDelegation(Class[] classes, String name, boolean isClass)
+        throws ClassNotFoundException, ResourceNotFoundException
+    {
+        // Start from 1 to skip security manager class.
+        for (int i = 1; i < classes.length; i++)
+        {
+            // Find the first class on the call stack that is not from
+            // the class loader that loaded the Felix classes or is not
+            // a class loader or class itself, because we want to ignore
+            // calls to ClassLoader.loadClass() and Class.forName() since
+            // we are trying to find out who instigated the class load.
+            // Also ignore inner classes of class loaders, since we can
+            // assume they are a class loader too.
+
+            // TODO: FRAMEWORK - This check is a hack and we should see if we can think
+            // of another way to do it, since it won't necessarily work in all situations.
+            // Since Felix uses threads for changing the start level
+            // and refreshing packages, it is possible that there are no
+            // bundle classes on the call stack; therefore, as soon as we
+            // see Thread on the call stack we exit this loop. Other cases
+            // where bundles actually use threads are not an issue because
+            // the bundle classes will be on the call stack before the
+            // Thread class.
+            if (Thread.class.equals(classes[i]))
+            {
+                break;
+            }
+            // Break if the current class came from a bundle, since we should
+            // not implicitly boot delegate in that case.
+            else if (isClassLoadedFromBundleRevision(classes[i]))
+            {
+                break;
+            }
+            // Break if this goes through BundleImpl because it must be a call
+            // to Bundle.loadClass() which should not implicitly boot delegate.
+            else if (BundleImpl.class.equals(classes[i]))
+            {
+                break;
+            }
+            else if (isClassExternal(classes[i]))
+            {
+                try
+                {
+                    // Return the class or resource from the parent class loader.
+                    return (isClass)
+                        ? (Object) m_secureAction.getClassLoader(this.getClass()).loadClass(name)
+                        : (Object) m_secureAction.getClassLoader(this.getClass()).getResource(name);
+                }
+                catch (NoClassDefFoundError ex)
+                {
+                    // Ignore, will return null
+                }
+                break;
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isClassLoadedFromBundleRevision(Class clazz)
+    {
+        // The target class is loaded by a bundle class loader,
+        // then return true.
+        if (BundleClassLoader.class.isInstance(m_secureAction.getClassLoader(clazz)))
+        {
+            return true;
+        }
+
+        // If the target class was loaded from a class loader that
+        // came from a bundle, then return true.
+        ClassLoader last = null;
+        for (ClassLoader cl = m_secureAction.getClassLoader(clazz);
+            (cl != null) && (last != cl);
+            cl = m_secureAction.getClassLoader(cl.getClass()))
+        {
+            last = cl;
+            if (BundleClassLoader.class.isInstance(cl))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Tries to determine whether the given class is part of the framework or not.
+     * Framework classes include everything in org.apache.felix.framework.* and
+     * org.osgi.framework.*. We also consider ClassLoader and Class to be internal
+     * classes, because they are inserted into the stack trace as a result of
+     * method overloading. Typically, ClassLoader or Class will be mixed in
+     * between framework classes or will be at the point where the class loading
+     * request enters the framework class loading mechanism, which will then be
+     * followed by either bundle or external code, which will then exit our
+     * attempt to determine if we should boot delegate or not. Other standard
+     * class loaders, like URLClassLoader, are considered external classes and
+     * should trigger boot delegation. This means that bundles can create standard
+     * class loaders to get access to boot packages, but this is the standard
+     * behavior of class loaders.
+     * @param clazz the class to determine if it is external or not.
+     * @return <tt>true</tt> if the class is external, otherwise <tt>false</tt>.
+     */
+    private boolean isClassExternal(Class clazz)
+    {
+        if (clazz.getName().startsWith("org.apache.felix.framework."))
+        {
+            return false;
+        }
+        else if (clazz.getName().startsWith("org.osgi.framework."))
+        {
+            return false;
+        }
+        else if (ClassLoader.class.equals(clazz))
+        {
+            return false;
+        }
+        else if (Class.class.equals(clazz))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    synchronized boolean isActivationTriggered()
+    {
+        return m_isActivationTriggered;
+    }
+
+    boolean isActivationTrigger(String pkgName)
+    {
+        List<String> activationIncludes = m_revision.getActivationIncludes();
+        List<String> activationExcludes = m_revision.getActivationExcludes();
+
+        if ((activationIncludes == null) && (activationExcludes == null))
+        {
+            return true;
+        }
+
+        // If there are no include filters then all classes are included
+        // by default, otherwise try to find one match.
+        boolean included = (activationIncludes == null);
+        for (int i = 0;
+            (!included) && (activationIncludes != null) && (i < activationIncludes.size());
+            i++)
+        {
+            included = activationIncludes.get(i).equals(pkgName);
+        }
+
+        // If there are no exclude filters then no classes are excluded
+        // by default, otherwise try to find one match.
+        boolean excluded = false;
+        for (int i = 0;
+            (!excluded) && (activationExcludes != null) && (i < activationExcludes.size());
+            i++)
+        {
+            excluded = activationExcludes.get(i).equals(pkgName);
+        }
+        return included && !excluded;
+    }
+
+    static class ToLocalUrlEnumeration implements Enumeration
+    {
+        final Enumeration m_enumeration;
+
+        ToLocalUrlEnumeration(Enumeration enumeration)
+        {
+            m_enumeration = enumeration;
+        }
+
+        public boolean hasMoreElements()
+        {
+            return m_enumeration.hasMoreElements();
+        }
+
+        public Object nextElement()
+        {
+            return convertToLocalUrl((URL) m_enumeration.nextElement());
+        }
+    }
+
+    public class BundleClassLoaderJava5 extends BundleClassLoader
+    {
+        public BundleClassLoaderJava5(ClassLoader parent)
+        {
+            super(parent);
+        }
+
+        @Override
+        public Enumeration getResources(String name)
+        {
+            Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
+            if (m_useLocalURLs)
+            {
+                urls = new ToLocalUrlEnumeration(urls);
+            }
+            return urls;
+        }
+
+        @Override
+        protected Enumeration findResources(String name)
+        {
+            return BundleWiringImpl.this.getResourcesLocal(name);
+        }
+    }
+
+    public class BundleClassLoader extends SecureClassLoader implements BundleReference
+    {
+        private final Map m_jarContentToDexFile;
+        private Object[][] m_cachedLibs = new Object[0][];
+        private static final int LIBNAME_IDX = 0;
+        private static final int LIBPATH_IDX = 1;
+
+        public BundleClassLoader(ClassLoader parent)
+        {
+            super(parent);
+            if (m_dexFileClassLoadClass != null)
+            {
+                m_jarContentToDexFile = new HashMap();
+            }
+            else
+            {
+                m_jarContentToDexFile = null;
+            }
+        }
+
+        public Bundle getBundle()
+        {
+            return BundleWiringImpl.this.getBundle();
+        }
+
+        @Override
+        protected Class loadClass(String name, boolean resolve)
+            throws ClassNotFoundException
+        {
+            Class clazz = null;
+
+            // Make sure the class was not already loaded.
+            synchronized (this)
+            {
+                clazz = findLoadedClass(name);
+            }
+
+            if (clazz == null)
+            {
+                try
+                {
+                    clazz = (Class) findClassOrResourceByDelegation(name, true);
+                }
+                catch (ResourceNotFoundException ex)
+                {
+                    // This should never happen since we are asking for a class,
+                    // so just ignore it.
+                }
+                catch (ClassNotFoundException cnfe)
+                {
+                    ClassNotFoundException ex = cnfe;
+                    String msg = name;
+                    if (m_logger.getLogLevel() >= Logger.LOG_DEBUG)
+                    {
+                        msg = diagnoseClassLoadError(m_resolver, m_revision, name);
+                        ex = (msg != null)
+                            ? new ClassNotFoundException(msg, cnfe)
+                            : ex;
+                    }
+                    throw ex;
+                }
+            }
+
+            // Resolve the class and return it.
+            if (resolve)
+            {
+                resolveClass(clazz);
+            }
+            return clazz;
+        }
+
+        @Override
+        protected Class findClass(String name) throws ClassNotFoundException
+        {
+            Class clazz = null;
+
+            // Search for class in bundle revision.
+            if (clazz == null)
+            {
+                String actual = name.replace('.', '/') + ".class";
+
+                byte[] bytes = null;
+
+                // Check the bundle class path.
+                Content content = null;
+                for (int i = 0;
+                    (bytes == null) &&
+                    (i < m_contentPath.length); i++)
+                {
+                    bytes = m_contentPath[i].getEntryAsBytes(actual);
+                    content = m_contentPath[i];
+                }
+
+                if (bytes != null)
+                {
+                    // Get package name.
+                    String pkgName = Util.getClassPackage(name);
+
+                    // Before we actually attempt to define the class, grab
+                    // the lock for this class loader and make sure than no
+                    // other thread has defined this class in the meantime.
+                    synchronized (this)
+                    {
+                        clazz = findLoadedClass(name);
+
+                        if (clazz == null)
+                        {
+                            int activationPolicy = 
+                                ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
+                                ? ((BundleRevisionImpl) ((BundleImpl) getBundle())
+                                    .getCurrentRevision()).getDeclaredActivationPolicy()
+                                : EAGER_ACTIVATION;
+
+                            // If the revision is using deferred activation, then if
+                            // we load this class from this revision we need to activate
+                            // the bundle before returning the class. We will short
+                            // circuit the trigger matching if the trigger is already
+                            // tripped.
+                            boolean isTriggerClass = m_isActivationTriggered
+                                ? false : isActivationTrigger(pkgName);
+                            if (!m_isActivationTriggered
+                                && isTriggerClass
+                                && (activationPolicy == BundleRevisionImpl.LAZY_ACTIVATION)
+                                && (getBundle().getState() == Bundle.STARTING))
+                            {
+                                List deferredList = (List) m_deferredActivation.get();
+                                if (deferredList == null)
+                                {
+                                    deferredList = new ArrayList();
+                                    m_deferredActivation.set(deferredList);
+                                }
+                                deferredList.add(new Object[] { name, getBundle() });
+                            }
+                            // We need to try to define a Package object for the class
+                            // before we call defineClass() if we haven't already
+                            // created it.
+                            if (pkgName.length() > 0)
+                            {
+                                if (getPackage(pkgName) == null)
+                                {
+                                    Object[] params = definePackage(pkgName);
+                                    if (params != null)
+                                    {
+                                        definePackage(
+                                            pkgName,
+                                            (String) params[0],
+                                            (String) params[1],
+                                            (String) params[2],
+                                            (String) params[3],
+                                            (String) params[4],
+                                            (String) params[5],
+                                            null);
+                                    }
+                                    else
+                                    {
+                                        definePackage(pkgName, null, null,
+                                            null, null, null, null, null);
+                                    }
+                                }
+                            }
+
+                            // If we can load the class from a dex file do so
+                            if (content instanceof JarContent)
+                            {
+                                try
+                                {
+                                    clazz = getDexFileClass((JarContent) content, name, this);
+                                }
+                                catch (Exception ex)
+                                {
+                                    // Looks like we can't
+                                }
+                            }
+
+                            if (clazz == null)
+                            {
+                                // If we have a security context, then use it to
+                                // define the class with it for security purposes,
+                                // otherwise define the class without a protection domain.
+                                if (m_protectionDomain != null)
+                                {
+                                    clazz = defineClass(name, bytes, 0, bytes.length,
+                                        m_protectionDomain);
+                                }
+                                else
+                                {
+                                    clazz = defineClass(name, bytes, 0, bytes.length);
+                                }
+                            }
+
+                            // At this point if we have a trigger class, then the deferred
+                            // activation trigger has tripped.
+                            if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
+                            {
+// TODO: OSGi R4.3 - This isn't protected by the correct lock.
+                                m_isActivationTriggered = true;
+                            }
+                        }
+                    }
+
+                    // Perform deferred activation without holding the class loader lock,
+                    // if the class we are returning is the instigating class.
+                    List deferredList = (List) m_deferredActivation.get();
+                    if ((deferredList != null)
+                        && (deferredList.size() > 0)
+                        && ((Object[]) deferredList.get(0))[0].equals(name))
+                    {
+                        for (int i = deferredList.size() - 1; i >= 0; i--)
+                        {
+                            try
+                            {
+                                ((BundleImpl) ((Object[]) deferredList.get(i))[1]).getFramework().activateBundle(
+                                    (BundleImpl) ((Object[]) deferredList.get(i))[1], true);
+                            }
+                            catch (BundleException ex)
+                            {
+                                ex.printStackTrace();
+                            }
+                        }
+                        deferredList.clear();
+                    }
+                }
+            }
+
+            return clazz;
+        }
+
+        private Object[] definePackage(String pkgName)
+        {
+            String spectitle = (String) m_revision.getHeaders().get("Specification-Title");
+            String specversion = (String) m_revision.getHeaders().get("Specification-Version");
+            String specvendor = (String) m_revision.getHeaders().get("Specification-Vendor");
+            String impltitle = (String) m_revision.getHeaders().get("Implementation-Title");
+            String implversion = (String) m_revision.getHeaders().get("Implementation-Version");
+            String implvendor = (String) m_revision.getHeaders().get("Implementation-Vendor");
+            if ((spectitle != null)
+                || (specversion != null)
+                || (specvendor != null)
+                || (impltitle != null)
+                || (implversion != null)
+                || (implvendor != null))
+            {
+                return new Object[] {
+                    spectitle, specversion, specvendor, impltitle, implversion, implvendor
+                };
+            }
+            return null;
+        }
+
+        private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
+            throws Exception
+        {
+            if (m_jarContentToDexFile == null)
+            {
+                return null;
+            }
+
+            Object dexFile = null;
+
+            if (!m_jarContentToDexFile.containsKey(content))
+            {
+                try
+                {
+                    if (m_dexFileClassLoadDex != null)
+                    {
+                        dexFile = m_dexFileClassLoadDex.invoke(null, 
+                            new Object[]{content.getFile().getAbsolutePath(), 
+                                content.getFile().getAbsolutePath() + ".dex", new Integer(0)});
+                    }
+                    else
+                    {
+                        dexFile = m_dexFileClassConstructor.newInstance(
+                            new Object[] { content.getFile() });
+                    }
+                }
+                finally
+                {
+                    m_jarContentToDexFile.put(content, dexFile);
+                }
+            }
+            else
+            {
+                dexFile = m_jarContentToDexFile.get(content);
+            }
+
+            if (dexFile != null)
+            {
+                return (Class) m_dexFileClassLoadClass.invoke(dexFile,
+                    new Object[] { name.replace('.','/'), loader });
+            }
+            return null;
+        }
+
+        @Override
+        public URL getResource(String name)
+        {
+            URL url = BundleWiringImpl.this.getResourceByDelegation(name);
+            if (m_useLocalURLs)
+            {
+                url = convertToLocalUrl(url);
+            }
+            return url;
+        }
+
+        @Override
+        protected URL findResource(String name)
+        {
+            return BundleWiringImpl.this.getResourceLocal(name);
+        }
+
+        // The findResources() method should only look at the revision itself, but
+        // instead it tries to delegate because in Java version prior to 1.5 the
+        // getResources() method was final and could not be overridden. We should
+        // override getResources() like getResource() to make it delegate, but we
+        // can't. As a workaround, we make findResources() delegate instead.
+        @Override
+        protected Enumeration findResources(String name)
+        {
+            Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
+            if (m_useLocalURLs)
+            {
+                urls = new ToLocalUrlEnumeration(urls);
+            }
+            return urls;
+        }
+
+        @Override
+        protected String findLibrary(String name)
+        {
+            // Remove leading slash, if present.
+            if (name.startsWith("/"))
+            {
+                name = name.substring(1);
+            }
+
+            String result = null;
+            // CONCURRENCY: In the long run, we might want to break this
+            // sync block in two to avoid manipulating the cache while
+            // holding the lock, but for now we will do it the simple way.
+            synchronized (this)
+            {
+                // Check to make sure we haven't already found this library.
+                for (int i = 0; (result == null) && (i < m_cachedLibs.length); i++)
+                {
+                    if (m_cachedLibs[i][LIBNAME_IDX].equals(name))
+                    {
+                        result = (String) m_cachedLibs[i][LIBPATH_IDX];
+                    }
+                }
+
+                // If we don't have a cached result, see if we have a matching
+                // native library.
+                if (result == null)
+                {
+                    List<R4Library> libs = getNativeLibraries();
+                    for (int libIdx = 0; (libs != null) && (libIdx < libs.size()); libIdx++)
+                    {
+                        if (libs.get(libIdx).match(m_configMap, name))
+                        {
+                            // Search bundle content first for native library.
+                            result = m_revision.getContent().getEntryAsNativeLibrary(
+                                libs.get(libIdx).getEntryName());
+                            // If not found, then search fragments in order.
+                            for (int i = 0;
+                                (result == null) && (m_fragmentContents != null)
+                                    && (i < m_fragmentContents.length);
+                                i++)
+                            {
+                                result = m_fragmentContents[i].getEntryAsNativeLibrary(
+                                    libs.get(libIdx).getEntryName());
+                            }
+                        }
+                    }
+
+                    // Remember the result for future requests.
+                    if (result != null)
+                    {
+                        Object[][] tmp = new Object[m_cachedLibs.length + 1][];
+                        System.arraycopy(m_cachedLibs, 0, tmp, 0, m_cachedLibs.length);
+                        tmp[m_cachedLibs.length] = new Object[] { name, result };
+                        m_cachedLibs = tmp;
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        @Override
+        public String toString()
+        {
+            return BundleWiringImpl.this.toString();
+        }
+    }
+
+    static URL convertToLocalUrl(URL url)
+    {
+        if (url.getProtocol().equals("bundle"))
+        {
+            try
+            {
+                url = ((URLHandlersBundleURLConnection)
+                    url.openConnection()).getLocalURL();
+            }
+            catch (IOException ex)
+            {
+                // Ignore and add original url.
+            }
+        }
+        return url;
+    }
+
+    private static String diagnoseClassLoadError(
+        StatefulResolver resolver, BundleRevision revision, String name)
+    {
+        // We will try to do some diagnostics here to help the developer
+        // deal with this exception.
+
+        // Get package name.
+        String pkgName = Util.getClassPackage(name);
+        if (pkgName.length() == 0)
+        {
+            return null;
+        }
+
+        // First, get the bundle string of the revision doing the class loader.
+        String importer = revision.getBundle().toString();
+
+        // Next, check to see if the revision imports the package.
+        List<BundleWire> wires = (revision.getWiring() == null)
+            ? null : revision.getWiring().getProvidedWires(null);
+        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        {
+            if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+            {
+                String exporter = wires.get(i).getProviderWiring().getBundle().toString();
+
+                StringBuffer sb = new StringBuffer("*** Package '");
+                sb.append(pkgName);
+                sb.append("' is imported by bundle ");
+                sb.append(importer);
+                sb.append(" from bundle ");
+                sb.append(exporter);
+                sb.append(", but the exported package from bundle ");
+                sb.append(exporter);
+                sb.append(" does not contain the requested class '");
+                sb.append(name);
+                sb.append("'. Please verify that the class name is correct in the importing bundle ");
+                sb.append(importer);
+                sb.append(" and/or that the exported package is correctly bundled in ");
+                sb.append(exporter);
+                sb.append(". ***");
+
+                return sb.toString();
+            }
+        }
+
+        // Next, check to see if the package was optionally imported and
+        // whether or not there is an exporter available.
+        List<BundleRequirement> reqs = revision.getWiring().getRequirements(null);
+/*
+* TODO: RB - Fix diagnostic message for optional imports.
+        for (int i = 0; (reqs != null) && (i < reqs.length); i++)
+        {
+            if (reqs[i].getName().equals(pkgName) && reqs[i].isOptional())
+            {
+                // Try to see if there is an exporter available.
+                IModule[] exporters = getResolvedExporters(reqs[i], true);
+                exporters = (exporters.length == 0)
+                    ? getUnresolvedExporters(reqs[i], true) : exporters;
+
+                // An exporter might be available, but it may have attributes
+                // that do not match the importer's required attributes, so
+                // check that case by simply looking for an exporter of the
+                // desired package without any attributes.
+                if (exporters.length == 0)
+                {
+                    IRequirement pkgReq = new Requirement(
+                        ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+                    exporters = getResolvedExporters(pkgReq, true);
+                    exporters = (exporters.length == 0)
+                        ? getUnresolvedExporters(pkgReq, true) : exporters;
+                }
+
+                long expId = (exporters.length == 0)
+                    ? -1 : Util.getBundleIdFromModuleId(exporters[0].getId());
+
+                StringBuffer sb = new StringBuffer("*** Class '");
+                sb.append(name);
+                sb.append("' was not found, but this is likely normal since package '");
+                sb.append(pkgName);
+                sb.append("' is optionally imported by bundle ");
+                sb.append(impId);
+                sb.append(".");
+                if (exporters.length > 0)
+                {
+                    sb.append(" However, bundle ");
+                    sb.append(expId);
+                    if (reqs[i].isSatisfied(
+                        Util.getExportPackage(exporters[0], reqs[i].getName())))
+                    {
+                        sb.append(" does export this package. Bundle ");
+                        sb.append(expId);
+                        sb.append(" must be installed before bundle ");
+                        sb.append(impId);
+                        sb.append(" is resolved or else the optional import will be ignored.");
+                    }
+                    else
+                    {
+                        sb.append(" does export this package with attributes that do not match.");
+                    }
+                }
+                sb.append(" ***");
+
+                return sb.toString();
+            }
+        }
+*/
+        // Next, check to see if the package is dynamically imported by the revision.
+        if (resolver.isAllowedDynamicImport(revision, pkgName))
+        {
+            // Try to see if there is an exporter available.
+            Map<String, String> dirs = Collections.EMPTY_MAP;
+            Map<String, Object> attrs = new HashMap<String, Object>(1);
+            attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+            BundleRequirementImpl req = new BundleRequirementImpl(
+                revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
+            Set<BundleCapability> exporters = resolver.getCandidates(req, false);
+
+            BundleRevision provider = null;
+            try
+            {
+                provider = resolver.resolve(revision, pkgName);
+            }
+            catch (Exception ex)
+            {
+                provider = null;
+            }
+
+            String exporter = (exporters.isEmpty())
+                ? null : exporters.iterator().next().getRevision().getBundle().toString();
+
+            StringBuffer sb = new StringBuffer("*** Class '");
+            sb.append(name);
+            sb.append("' was not found, but this is likely normal since package '");
+            sb.append(pkgName);
+            sb.append("' is dynamically imported by bundle ");
+            sb.append(importer);
+            sb.append(".");
+            if ((exporters.size() > 0) && (provider == null))
+            {
+                sb.append(" However, bundle ");
+                sb.append(exporter);
+                sb.append(" does export this package with attributes that do not match.");
+            }
+            sb.append(" ***");
+
+            return sb.toString();
+        }
+
+        // Next, check to see if there are any exporters for the package at all.
+        Map<String, String> dirs = Collections.EMPTY_MAP;
+        Map<String, Object> attrs = new HashMap<String, Object>(1);
+        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+        BundleRequirementImpl req = new BundleRequirementImpl(
+            revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
+        Set<BundleCapability> exports = resolver.getCandidates(req, false);
+        if (exports.size() > 0)
+        {
+            boolean classpath = false;
+            try
+            {
+                m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
+                classpath = true;
+            }
+            catch (NoClassDefFoundError err)
+            {
+                // Ignore
+            }
+            catch (Exception ex)
+            {
+                // Ignore
+            }
+
+            String exporter = exports.iterator().next().getRevision().getBundle().toString();
+
+            StringBuffer sb = new StringBuffer("*** Class '");
+            sb.append(name);
+            sb.append("' was not found because bundle ");
+            sb.append(importer);
+            sb.append(" does not import '");
+            sb.append(pkgName);
+            sb.append("' even though bundle ");
+            sb.append(exporter);
+            sb.append(" does export it.");
+            if (classpath)
+            {
+                sb.append(" Additionally, the class is also available from the system class loader. There are two fixes: 1) Add an import for '");
+                sb.append(pkgName);
+                sb.append("' to bundle ");
+                sb.append(importer);
+                sb.append("; imports are necessary for each class directly touched by bundle code or indirectly touched, such as super classes if their methods are used. ");
+                sb.append("2) Add package '");
+                sb.append(pkgName);
+                sb.append("' to the '");
+                sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+                sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+            }
+            else
+            {
+                sb.append(" To resolve this issue, add an import for '");
+                sb.append(pkgName);
+                sb.append("' to bundle ");
+                sb.append(importer);
+                sb.append(".");
+            }
+            sb.append(" ***");
+
+            return sb.toString();
+        }
+
+        // Next, try to see if the class is available from the system
+        // class loader.
+        try
+        {
+            m_secureAction.getClassLoader(BundleClassLoader.class).loadClass(name);
+
+            StringBuffer sb = new StringBuffer("*** Package '");
+            sb.append(pkgName);
+            sb.append("' is not imported by bundle ");
+            sb.append(importer);
+            sb.append(", nor is there any bundle that exports package '");
+            sb.append(pkgName);
+            sb.append("'. However, the class '");
+            sb.append(name);
+            sb.append("' is available from the system class loader. There are two fixes: 1) Add package '");
+            sb.append(pkgName);
+            sb.append("' to the '");
+            sb.append(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+            sb.append("' property and modify bundle ");
+            sb.append(importer);
+            sb.append(" to import this package; this causes the system bundle to export class path packages. 2) Add package '");
+            sb.append(pkgName);
+            sb.append("' to the '");
+            sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+            sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+            sb.append(" ***");
+
+            return sb.toString();
+        }
+        catch (Exception ex2)
+        {
+        }
+
+        // Finally, if there are no imports or exports for the package
+        // and it is not available on the system class path, simply
+        // log a message saying so.
+        StringBuffer sb = new StringBuffer("*** Class '");
+        sb.append(name);
+        sb.append("' was not found. Bundle ");
+        sb.append(importer);
+        sb.append(" does not import package '");
+        sb.append(pkgName);
+        sb.append("', nor is the package exported by any other bundle or available from the system class loader.");
+        sb.append(" ***");
+
+        return sb.toString();
+    }
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java b/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
index 51c17f8..7e039c7 100644
--- a/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
+++ b/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
@@ -43,7 +43,7 @@
     {
         m_bundle = bundle;
         BundleRevision br = m_bundle.getCurrentRevision();
-        List<BundleRevision> fragments = ((BundleRevisionImpl) br).getFragments();
+        List<BundleRevision> fragments = ((BundleWiringImpl) br.getWiring()).getFragments();
         if (includeFragments && (fragments != null))
         {
             m_revisions = new ArrayList(fragments.size() + 1);
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 f463c3a..be07bbc 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -27,6 +27,7 @@
 import java.security.AccessControlException;
 import java.security.AllPermission;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,13 +37,15 @@
 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;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.util.manifestparser.R4Library;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
@@ -53,6 +56,7 @@
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
 
 /**
  * The ExtensionManager class is used in several ways.
@@ -115,6 +119,7 @@
     }
 
     private final Logger m_logger;
+    private final Map m_configMap;
     private final Map m_headerMap = new StringMap(false);
     private final BundleRevision m_systemBundleRevision;
     private List<BundleCapability> m_capabilities = null;
@@ -130,6 +135,7 @@
     private ExtensionManager()
     {
         m_logger = null;
+        m_configMap = null;
         m_systemBundleRevision = null;
         m_extensions = new ArrayList();
         m_extensionsCache = new Bundle[0];
@@ -148,19 +154,20 @@
      * @param config the configuration to read properties from.
      * @param systemBundleInfo the info to change if we need to add exports.
      */
-    ExtensionManager(Logger logger, Felix felix)
+    ExtensionManager(Logger logger, Map configMap, Felix felix)
     {
+        m_logger = logger;
+        m_configMap = configMap;
         m_systemBundleRevision = new ExtensionManagerRevision(felix);
         m_extensions = null;
         m_extensionsCache = null;
         m_names = null;
         m_sourceToExtensions = null;
-        m_logger = logger;
 
 // TODO: FRAMEWORK - Not all of this stuff really belongs here, probably only exports.
         // Populate system bundle header map.
         m_headerMap.put(FelixConstants.BUNDLE_VERSION,
-            felix.getConfig().get(FelixConstants.FELIX_VERSION_PROPERTY));
+            m_configMap.get(FelixConstants.FELIX_VERSION_PROPERTY));
         m_headerMap.put(FelixConstants.BUNDLE_SYMBOLICNAME,
             FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
         m_headerMap.put(FelixConstants.BUNDLE_NAME, "System Bundle");
@@ -176,21 +183,21 @@
         // We must construct the system bundle's export metadata.
         // Get configuration property that specifies which class path
         // packages should be exported by the system bundle.
-        String syspkgs = (String) felix.getConfig().get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES);
+        String syspkgs = (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES);
         // If no system packages were specified, load our default value.
         syspkgs = (syspkgs == null)
             ? Util.getDefaultProperty(logger, Constants.FRAMEWORK_SYSTEMPACKAGES)
             : syspkgs;
         syspkgs = (syspkgs == null) ? "" : syspkgs;
         // If any extra packages are specified, then append them.
-        String extra = (String) felix.getConfig().get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+        String extra = (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
         syspkgs = (extra == null) ? syspkgs : syspkgs + "," + extra;
         m_headerMap.put(FelixConstants.BUNDLE_MANIFESTVERSION, "2");
         m_headerMap.put(FelixConstants.EXPORT_PACKAGE, syspkgs);
         try
         {
             ManifestParser mp = new ManifestParser(
-                m_logger, felix.getConfig(), m_systemBundleRevision, m_headerMap);
+                m_logger, m_configMap, m_systemBundleRevision, m_headerMap);
             List<BundleCapability> caps = aliasSymbolicName(mp.getCapabilities());
             setCapabilities(caps);
         }
@@ -635,14 +642,17 @@
     class ExtensionManagerRevision extends BundleRevisionImpl
     {
         private final Version m_version;
+        private volatile BundleWiring m_wiring;
+
         ExtensionManagerRevision(Felix felix)
         {
-            super(m_logger, felix.getConfig(), felix, "0",
+            super(m_logger, m_configMap, felix, "0",
                 felix.getBootPackages(), felix.getBootPackageWildcards());
             m_version = new Version((String)
-                felix.getConfig().get(FelixConstants.FELIX_VERSION_PROPERTY));
+                m_configMap.get(FelixConstants.FELIX_VERSION_PROPERTY));
         }
 
+        @Override
         public Map getHeaders()
         {
             synchronized (ExtensionManager.this)
@@ -651,6 +661,7 @@
             }
         }
 
+        @Override
         public List<BundleCapability> getDeclaredCapabilities(String namespace)
         {
             synchronized (ExtensionManager.this)
@@ -659,6 +670,85 @@
             }
         }
 
+        @Override
+        public String getSymbolicName()
+        {
+            return FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME;
+        }
+
+        @Override
+        public Version getVersion()
+        {
+            return m_version;
+        }
+
+        @Override
+        public void close()
+        {
+            // Nothing needed here.
+        }
+
+        @Override
+        public Content getContent()
+        {
+            return ExtensionManager.this;
+        }
+
+        @Override
+        public URL getEntry(String name)
+        {
+            // There is no content for the system bundle, so return null.
+            return null;
+        }
+
+        @Override
+        public boolean hasInputStream(int index, String urlPath)
+        {
+            return (getClass().getClassLoader().getResource(urlPath) != null);
+        }
+
+        @Override
+        public InputStream getInputStream(int index, String urlPath)
+        {
+            return getClass().getClassLoader().getResourceAsStream(urlPath);
+        }
+
+        @Override
+        public URL getLocalURL(int index, String urlPath)
+        {
+            return getClass().getClassLoader().getResource(urlPath);
+        }
+
+        @Override
+        public void resolve(
+            List<BundleRevision> fragments, List<ResolverWire> rws,
+            Map<ResolverWire, Set<String>> requiredPkgWires) throws Exception
+        {
+            m_wiring = new ExtensionManagerWiring(
+                m_logger, m_configMap, null, this, fragments, rws, requiredPkgWires);
+        }
+
+        @Override
+        public BundleWiring getWiring()
+        {
+            return m_wiring;
+        }
+    }
+
+    class ExtensionManagerWiring extends BundleWiringImpl
+    {
+        ExtensionManagerWiring(
+            Logger logger, Map configMap, StatefulResolver resolver,
+            BundleRevisionImpl revision, List<BundleRevision> fragments,
+            List<ResolverWire> resolverWires,
+            Map<ResolverWire, Set<String>> requiredPkgWires)
+            throws Exception
+        {
+            super(logger, configMap, resolver, revision,
+                fragments, resolverWires, requiredPkgWires);
+        }
+
+        @Override
         public List<BundleCapability> getCapabilities(String namespace)
         {
             synchronized (ExtensionManager.this)
@@ -667,16 +757,13 @@
             }
         }
 
-        public String getSymbolicName()
+        @Override
+        public List<R4Library> getNativeLibraries()
         {
-            return FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME;
+            return Collections.EMPTY_LIST;
         }
 
-        public Version getVersion()
-        {
-            return m_version;
-        }
-
+        @Override
         public Class getClassByDelegation(String name) throws ClassNotFoundException
         {
             Class clazz = null;
@@ -720,11 +807,13 @@
             return clazz;
         }
 
+        @Override
         public URL getResourceByDelegation(String name)
         {
             return getClass().getClassLoader().getResource(name);
         }
 
+        @Override
         public Enumeration getResourcesByDelegation(String name)
         {
            try
@@ -737,53 +826,13 @@
            }
         }
 
-        public Logger getLogger()
-        {
-            return m_logger;
-        }
-
-        public Map getConfig()
-        {
-            return null;
-        }
-
-        public StatefulResolver getResolver()
-        {
-            return null;
-        }
-
-        public void attachFragmentContents(Content[] fragmentContents)
-            throws Exception
-        {
-            throw new UnsupportedOperationException("Should not be used!");
-        }
-
-        public void close()
+        @Override
+        public void dispose()
         {
             // Nothing needed here.
         }
 
-        public Content getContent()
-        {
-            return ExtensionManager.this;
-        }
-
-        public URL getEntry(String name)
-        {
-            // There is no content for the system bundle, so return null.
-            return null;
-        }
-
-        public boolean hasInputStream(int index, String urlPath)
-        {
-            return (getClass().getClassLoader().getResource(urlPath) != null);
-        }
-
-        public InputStream getInputStream(int index, String urlPath)
-        {
-            return getClass().getClassLoader().getResourceAsStream(urlPath);
-        }
-
+        @Override
         public URL getLocalURL(int index, String urlPath)
         {
             return getClass().getClassLoader().getResource(urlPath);
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 db092bc..4889fa5 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -369,7 +369,7 @@
 
         // Create the extension manager, which we will use as the
         // revision for the system bundle.
-        m_extensionManager = new ExtensionManager(m_logger, this);
+        m_extensionManager = new ExtensionManager(m_logger, m_configMap, this);
         try
         {
             addRevision(m_extensionManager.getRevision());
@@ -1476,7 +1476,21 @@
         {
             return null;
         }
-        return ((BundleRevisionImpl) bundle.getCurrentRevision()).getResourceByDelegation(name);
+// TODO: OSGi R4.3 - Currently, we try to resolve resource requests in
+//       findClassOrResourceByDelegation() and fall back to local resource
+//       searching if it fails. Perhaps we should attempt the resolve here
+//       and do the local searching here. This means we could get rid of
+//       resolve attempts in findClassOrResourceByDelegation().
+        if (bundle.getCurrentRevision().getWiring() == null)
+        {
+            return ((BundleRevisionImpl) bundle.getCurrentRevision())
+                .getResourceLocal(name);
+        }
+        else
+        {
+            return ((BundleWiringImpl) bundle.getCurrentRevision().getWiring())
+                .getResourceByDelegation(name);
+        }
     }
 
     /**
@@ -1492,7 +1506,21 @@
         {
             return null;
         }
-        return ((BundleRevisionImpl) bundle.getCurrentRevision()).getResourcesByDelegation(name);
+// TODO: OSGi R4.3 - Currently, we try to resolve resource requests in
+//       findResourcesByDelegation() and fall back to local resource
+//       searching if it fails. Perhaps we should attempt the resolve here
+//       and do the local searching here. This means we could get rid of
+//       resolve attempts in findResourcesByDelegation().
+        if (bundle.getCurrentRevision().getWiring() == null)
+        {
+            return ((BundleRevisionImpl) bundle.getCurrentRevision())
+                .getResourcesLocal(name);
+        }
+        else
+        {
+            return ((BundleWiringImpl) bundle.getCurrentRevision().getWiring())
+                .getResourcesByDelegation(name);
+        }
     }
 
     /**
@@ -1651,7 +1679,8 @@
                 throw new ClassNotFoundException(name, ex);
             }
         }
-        return ((BundleRevisionImpl) bundle.getCurrentRevision()).getClassByDelegation(name);
+        return ((BundleWiringImpl)
+            bundle.getCurrentRevision().getWiring()).getClassByDelegation(name);
     }
 
     /**
@@ -3216,8 +3245,8 @@
                 Class sbClass = null;
                 try
                 {
-                    sbClass = ((BundleRevisionImpl) m_extensionManager
-                        .getRevision()).getClassByDelegation(clazz.getName());
+                    sbClass = ((BundleWiringImpl) m_extensionManager
+                        .getRevision().getWiring()).getClassByDelegation(clazz.getName());
                 }
                 catch (ClassNotFoundException ex)
                 {
@@ -3412,24 +3441,19 @@
                             BundleCapabilityImpl.PACKAGE_NAMESPACE,
                             Collections.EMPTY_MAP,
                             attrs);
-                        Set<BundleCapability> providers =
-                            m_resolver.getCandidates(req, false);
-                        // We only want resolved capabilities.
-                        for (Iterator<BundleCapability> it = providers.iterator();
-                            it.hasNext(); )
-                        {
-                            if (it.next().getRevision().getWiring() == null)
-                            {
-                                it.remove();
-                            }
-                        }
+                        Set<BundleCapability> providers = m_resolver.getCandidates(req, false);
 
                         // Search through the current providers to find the target revision.
-                        for (BundleCapability provider : providers)
+                        // We only want resolved capabilities.
+                        if (providers != null)
                         {
-                            if (provider == cap)
+                            for (BundleCapability provider : providers)
                             {
-                                list.add(new ExportedPackageImpl(this, bundle, br, cap));
+                                if ((provider.getRevision().getWiring() != null)
+                                    && (provider == cap))
+                                {
+                                    list.add(new ExportedPackageImpl(this, bundle, br, cap));
+                                }
                             }
                         }
                     }
@@ -3445,10 +3469,10 @@
 
         // Get all dependent revisions from all exporter revisions.
         List<BundleRevision> revisions = exporter.getRevisions();
-        for (int modIdx = 0; modIdx < revisions.size(); modIdx++)
+        for (int revIdx = 0; revIdx < revisions.size(); revIdx++)
         {
             List<BundleRevision> dependents =
-                ((BundleRevisionImpl) revisions.get(modIdx)).getDependents();
+                ((BundleRevisionImpl) revisions.get(revIdx)).getDependents();
             for (int depIdx = 0;
                 (dependents != null) && (depIdx < dependents.size());
                 depIdx++)
@@ -3475,24 +3499,31 @@
         {
             // Include any importers that have wires to the specific
             // exported package.
-            List<BundleRevision> dependents =
-                ((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentImporters();
-            for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
+            if (expRevisions.get(expIdx).getWiring() != null)
             {
-                BundleRevision providerRevision =
-                    ((BundleRevisionImpl) dependents.get(depIdx))
-                        .getImportedPackageSource(ep.getName());                
-                if ((providerRevision != null)
-                    && (providerRevision == expRevisions.get(expIdx)))
+                List<BundleRevision> dependents = ((BundleRevisionImpl)
+                    expRevisions.get(expIdx)).getDependentImporters();
+                for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
+                {
+                    if (dependents.get(depIdx).getWiring() != null)
+                    {
+                        BundleRevision providerRevision =
+                            ((BundleWiringImpl) dependents.get(depIdx).getWiring())
+                                .getImportedPackageSource(ep.getName());                
+                        if ((providerRevision != null)
+                            && (providerRevision == expRevisions.get(expIdx)))
+                        {
+                            list.add(dependents.get(depIdx).getBundle());
+                        }
+                    }
+                }
+                dependents = ((BundleRevisionImpl)
+                    expRevisions.get(expIdx)).getDependentRequirers();
+                for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
                 {
                     list.add(dependents.get(depIdx).getBundle());
                 }
             }
-            dependents = ((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentRequirers();
-            for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
-            {
-                list.add(dependents.get(depIdx).getBundle());
-            }
         }
 
         // Return the results.
@@ -3818,8 +3849,8 @@
             Class clazz;
             try
             {
-                clazz = ((BundleRevisionImpl)
-                    impl.getCurrentRevision()).getClassByDelegation(className);
+                clazz = ((BundleWiringImpl)
+                    impl.getCurrentRevision().getWiring()).getClassByDelegation(className);
             }
             catch (ClassNotFoundException ex)
             {
@@ -4206,7 +4237,7 @@
                     // 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 = ((BundleRevisionImpl)revision)
+                    provider = ((BundleWiringImpl) revision.getWiring())
                         .getImportedPackageSource(pkgName);
                     if (provider == null)
                     {
@@ -4225,12 +4256,13 @@
                             // Dynamically add new wire to importing revision.
                             if (dynamicWire != null)
                             {
-                                ((BundleRevisionImpl) revision).addDynamicWire(dynamicWire);
+                                ((BundleWiringImpl) revision.getWiring())
+                                    .addDynamicWire(dynamicWire);
                                 m_logger.log(
                                     Logger.LOG_DEBUG,
                                     "DYNAMIC WIRE: " + dynamicWire);
 
-                                provider = ((BundleRevisionImpl) revision)
+                                provider = ((BundleWiringImpl) revision.getWiring())
                                     .getImportedPackageSource(pkgName);
                             }
                         }
@@ -4262,7 +4294,7 @@
             // If the revision doesn't have dynamic imports, then just return
             // immediately.
             List<BundleRequirement> dynamics =
-                ((BundleRevisionImpl) revision).getResolvedDynamicRequirements();
+                ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements();
             if ((dynamics == null) || dynamics.isEmpty())
             {
                 return false;
@@ -4281,7 +4313,7 @@
 
             // If this revision already imports or requires this package, then
             // we cannot dynamically import it.
-            if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
+            if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
             {
                 return false;
             }
@@ -4361,64 +4393,54 @@
                         }
                     }
 
-                    ((BundleRevisionImpl) revision).setWires(resolverWires, requiredPkgWires);
-
-                    // Attach fragments, if any.
                     List<BundleRevision> fragments = hosts.get(revision);
-                    if (fragments != null)
+                    try
                     {
-                        try
+// TODO: OSGi R4.3 - Technically, this is where the revision becomes resolved,
+//       but we used to wait and mark it as resolved in the third phase below. 
+                        ((BundleRevisionImpl) revision).resolve(
+                            fragments, resolverWires, requiredPkgWires);
+                    }
+                    catch (Exception ex)
+                    {
+                        // This is a fatal error, so undo everything and
+                        // throw an exception.
+                        for (Entry<BundleRevision, List<ResolverWire>> reentry : wireMap.entrySet())
                         {
-                            ((BundleRevisionImpl) revision).attachFragments(fragments);
-                        }
-                        catch (Exception ex)
-                        {
-                            // This is a fatal error, so undo everything and
-                            // throw an exception.
-                            for (Entry<BundleRevision, List<ResolverWire>> reentry : wireMap.entrySet())
+                            revision = reentry.getKey();
+
+                            // Undo wires.
+                            try
                             {
-                                revision = reentry.getKey();
-
-                                // Undo wires.
-                                ((BundleRevisionImpl) revision).setWires(null, null);
-
-                                fragments = hosts.get(revision);
-                                if (fragments != null)
-                                {
-                                    try
-                                    {
-                                        // Undo fragments.
-                                        ((BundleRevisionImpl) revision).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.addRevision(revision);
-                                }
+                                ((BundleRevisionImpl) revision).resolve(null, null, 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;
                             }
 
-                            ResolveException re = new ResolveException(
-                                "Unable to attach fragments to " + revision,
-                                revision, null);
-                            re.initCause(ex);
-                            m_logger.log(
-                                Logger.LOG_ERROR,
-                                re.getMessage(), ex);
-                            throw re;
+                            // Reindex host with no fragments.
+                            m_resolverState.addRevision(revision);
                         }
 
-                        // Reindex host with attached 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;
                     }
+
+                    // Reindex host with attached fragments.
+                    m_resolverState.addRevision(revision);
                 }
 
                 // Third pass: Loop through the wire map to mark revision as resolved
@@ -4427,7 +4449,8 @@
                 {
                     BundleRevision revision = entry.getKey();
                     // Mark revision as resolved.
-                    ((BundleRevisionImpl) revision).setResolved();
+// TODO: OSGi R4.3 - See message above when we call BundleRevisionImpl.resolve().
+//                    ((BundleRevisionImpl) revision).setResolved();
                     // Update resolver state to remove substituted capabilities.
                     if (!Util.isFragment(revision))
                     {
@@ -4492,7 +4515,8 @@
                     BundleRevision revision = entry.getKey();
 
                     // Fire RESOLVED events for all fragments.
-                    List<BundleRevision> fragments = ((BundleRevisionImpl) revision).getFragments();
+                    List<BundleRevision> fragments =
+                        ((BundleWiringImpl) revision.getWiring()).getFragments();
                     for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
                     {
                         fireBundleEvent(BundleEvent.RESOLVED, fragments.get(i).getBundle());
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 f19531f..73ae668 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -197,14 +197,13 @@
         {
             List<Bundle> list = new ArrayList<Bundle>();
             // Iterate through revisions
-            List<BundleRevision> revisions = ((BundleImpl) bundle).getRevisions();
-            for (int modIdx = 0; modIdx < revisions.size(); modIdx++)
+            for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
             {
                 // Get attached fragments.
-                BundleRevisionImpl revision = (BundleRevisionImpl) revisions.get(modIdx);
-                if (revision.isResolved())
+                if (revision.getWiring() != null)
                 {
-                    List<BundleRevision> fragments = revision.getFragments();
+                    List<BundleRevision> fragments =
+                        ((BundleWiringImpl) revision.getWiring()).getFragments();
                     for (int i = 0; (fragments != null) && (i < fragments.size()); i++)
                     {
                         Bundle b = fragments.get(i).getBundle();
@@ -230,14 +229,12 @@
         {
             List<Bundle> list = new ArrayList<Bundle>();
             // Iterate through revisions
-            List<BundleRevision> revisions = ((BundleImpl) bundle).getRevisions();
-            for (int modIdx = 0; modIdx < revisions.size(); modIdx++)
+            for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
             {
                 // Get hosts
-                BundleRevisionImpl revision = (BundleRevisionImpl) revisions.get(modIdx);
-                if (revision.isResolved())
+                if (revision.getWiring() != null)
                 {
-                    List<BundleWire> hostWires = revision.getWires();
+                    List<BundleWire> hostWires = revision.getWiring().getRequiredWires(null);
                     for (int i = 0; (hostWires != null) && (i < hostWires.size()); i++)
                     {
                         Bundle b = hostWires.get(i).getProviderWiring().getBundle();
@@ -259,14 +256,12 @@
     public RequiredBundle[] getRequiredBundles(String symbolicName)
     {
         List list = new ArrayList();
-        Bundle[] bundles = m_felix.getBundles();
-        for (int i = 0; i < bundles.length; i++)
+        for (Bundle bundle : m_felix.getBundles())
         {
-            BundleImpl impl = (BundleImpl) bundles[i];
             if ((symbolicName == null)
-                || (symbolicName.equals(impl.getCurrentRevision().getSymbolicName())))
+                || (symbolicName.equals(bundle.getSymbolicName())))
             {
-                list.add(new RequiredBundleImpl(m_felix, impl));
+                list.add(new RequiredBundleImpl(m_felix, (BundleImpl) bundle));
             }
         }
         return (list.isEmpty())
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
index b76ade8..bdb4ade 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -145,7 +145,7 @@
             // If so, then the framework must have chosen to have the revision
             // import rather than export the package, so we need to remove the
             // corresponding package capability from the package capability set.
-            for (BundleWire w : ((BundleRevisionImpl) br).getWires())
+            for (BundleWire w : br.getWiring().getRequiredWires(null))
             {
                 if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
@@ -274,7 +274,9 @@
     {
         // Next, try to resolve any native code, since the revision is
         // not resolvable if its native code cannot be loaded.
-        List<R4Library> libs = ((BundleRevisionImpl) revision).getNativeLibraries();
+// TODO: OSGi R4.3 - Is it sufficient to just check declared native libs here?
+//        List<R4Library> libs = ((BundleWiringImpl) revision.getWiring()).getNativeLibraries();
+        List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
         if (libs != null)
         {
             String msg = null;
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index f544c4a..02b5fd4 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -519,7 +519,8 @@
                 try
                 {
                     Class requestClass =
-                        ((BundleRevisionImpl) requesterRevision).getClassByDelegation(className);
+                        ((BundleWiringImpl) requesterRevision.getWiring())
+                            .getClassByDelegation(className);
                     allow = getRegistration().isClassAccessible(requestClass);
                 }
                 catch (Exception ex)
@@ -544,14 +545,15 @@
                     try
                     {
                         // Try to load class from requester.
-                        Class requestClass =((BundleRevisionImpl)
-                            requesterRevision).getClassByDelegation(className);
+                        Class requestClass =((BundleWiringImpl)
+                            requesterRevision.getWiring()).getClassByDelegation(className);
                         try
                         {
                             // If requester has access to the class, verify it is the
                             // same class as the provider.
-                            allow = (((BundleRevisionImpl) providerRevision)
-                                .getClassByDelegation(className) == requestClass);
+                            allow = (((BundleWiringImpl)
+                                providerRevision.getWiring())
+                                    .getClassByDelegation(className) == requestClass);
                         }
                         catch (Exception ex)
                         {
@@ -585,8 +587,9 @@
                     try
                     {
                         // Load the class from the requesting bundle.
-                        Class requestClass = ((BundleRevisionImpl)
-                            requesterRevision).getClassByDelegation(className);
+                        Class requestClass = ((BundleWiringImpl)
+                            requesterRevision.getWiring())
+                                .getClassByDelegation(className);
                         // Get the service registration and ask it to check
                         // if the service object is assignable to the requesting
                         // bundle's class.
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index 54f34c5..6092980 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -126,8 +126,8 @@
         if (!((BundleRevisionImpl) m_targetRevision)
             .hasInputStream(m_classPathIdx, url.getPath()))
         {
-            URL newurl = ((BundleRevisionImpl)
-                m_targetRevision).getResourceByDelegation(url.getPath());
+            URL newurl = ((BundleWiringImpl)
+                m_targetRevision.getWiring()).getResourceByDelegation(url.getPath());
             if (newurl == null)
             {
                 throw new IOException("Resource does not exist: " + url);
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index c6d6a5c..066a303 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -31,6 +31,7 @@
 import java.util.TreeMap;
 import java.util.TreeSet;
 import org.apache.felix.framework.BundleRevisionImpl;
+import org.apache.felix.framework.BundleWiringImpl;
 import org.apache.felix.framework.resolver.Resolver.ResolverState;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
@@ -990,8 +991,11 @@
                     System.out.println("    " + req + ": " + candidates);
                 }
             }
+// TODO: OSGi R4.3 - We need to get dynamic requirements using public API
+//       then we might not need to make the BundleWiringImpl and BundleRevisionImpl
+//       classes public.
             reqs = (br.getWiring() != null)
-                ? ((BundleRevisionImpl) br).getResolvedDynamicRequirements()
+                ? ((BundleWiringImpl) br.getWiring()).getDynamicRequirements()
                 : ((BundleRevisionImpl) br).getDeclaredDynamicRequirements();
             for (BundleRequirement req : reqs)
             {
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 829098e..3110261 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
@@ -29,6 +29,7 @@
 import java.util.Set;
 import java.util.SortedSet;
 import org.apache.felix.framework.BundleRevisionImpl;
+import org.apache.felix.framework.BundleWiringImpl;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.util.Util;
@@ -62,7 +63,7 @@
         Map<BundleRevision, List<ResolverWire>> wireMap = new HashMap<BundleRevision, List<ResolverWire>>();
         Map<BundleRevision, Packages> revisionPkgMap = new HashMap<BundleRevision, Packages>();
 
-        if (!((BundleRevisionImpl) revision).isResolved())
+        if (revision.getWiring() == null)
         {
             boolean retryFragments;
             do
@@ -360,7 +361,7 @@
         // If the revision doesn't have dynamic imports, then just return
         // immediately.
         List<BundleRequirement> dynamics =
-            ((BundleRevisionImpl) revision).getResolvedDynamicRequirements();
+            ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements();
         if ((dynamics == null) || dynamics.isEmpty())
         {
             return null;
@@ -379,7 +380,7 @@
 
         // If this revision already imports or requires this package, then
         // we cannot dynamically import it.
-        if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
+        if (((BundleWiringImpl) revision.getWiring()).hasPackageSource(pkgName))
         {
             return null;
         }
@@ -466,7 +467,7 @@
         if (revision.getWiring() != null)
         {
             // Use wires to get actual requirements and satisfying capabilities.
-            for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
+            for (BundleWire wire : revision.getWiring().getRequiredWires(null))
             {
                 // Wrap the requirement as a hosted requirement
                 // if it comes from a fragment, since we will need
@@ -496,7 +497,7 @@
             // so check to see if there are candidates for any of its dynamic
             // imports.
             for (BundleRequirement req
-                : ((BundleRevisionImpl) revision).getResolvedDynamicRequirements())
+                : ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements())
             {
                 // Get the candidates for the current requirement.
                 SortedSet<BundleCapability> candCaps =
@@ -1171,7 +1172,7 @@
         // exports are substitutable.
         if (revision.getWiring() != null)
         {
-            for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
+            for (BundleWire wire : revision.getWiring().getRequiredWires(null))
             {
                 if (wire.getRequirement().getNamespace().equals(
                     BundleCapabilityImpl.PACKAGE_NAMESPACE))
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index 817ad66..8cc096f 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -329,17 +329,20 @@
 
     public static BundleWire getWire(BundleRevision br, String name)
     {
-        List<BundleWire> wires = ((BundleRevisionImpl) br).getWires();
-        if (wires != null)
+        if (br.getWiring() != null)
         {
-            for (BundleWire w : wires)
+            List<BundleWire> wires = br.getWiring().getRequiredWires(null);
+            if (wires != null)
             {
-                if (w.getCapability().getNamespace()
-                        .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
-                    w.getCapability().getAttributes()
-                        .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+                for (BundleWire w : wires)
                 {
-                    return w;
+                    if (w.getCapability().getNamespace()
+                            .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                        w.getCapability().getAttributes()
+                            .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+                    {
+                        return w;
+                    }
                 }
             }
         }
