Change class loader delegation to revision-to-revision instead
of revision-to-wire. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102809 13f79535-47bb-0310-9956-ffa450edef68
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 9e01017..f6d2c99 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.framework;
 
-import com.sun.xml.internal.ws.api.server.Module;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -29,9 +28,9 @@
 import org.apache.felix.framework.ext.SecurityProvider;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.FelixBundleWire;
 import org.osgi.framework.*;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
 
 class BundleImpl implements Bundle
 {
@@ -145,7 +144,7 @@
             }
             // Set wires to null, which will remove the revision from all
             // of its dependent revisions.
-            ((BundleRevisionImpl) br).setWires(null);
+            ((BundleRevisionImpl) br).setWires(null, null);
 
             // Close the revision's content.
             ((BundleRevisionImpl) br).close();
@@ -480,7 +479,7 @@
         // search the revision itself.
         if (Util.isFragment(bri))
         {
-            List<FelixBundleWire> hostWires = bri.getWires();
+            List<BundleWire> hostWires = bri.getWires();
             if ((hostWires != null) && (hostWires.size() > 0))
             {
                 bri = (BundleRevisionImpl) hostWires.get(0).getProviderWiring().getRevision();
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 18aa2fa..032419d 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -48,6 +48,7 @@
 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;
@@ -58,7 +59,7 @@
 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.FelixBundleWire;
+import org.apache.felix.framework.wiring.BundleWireImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.BundleReference;
@@ -102,7 +103,9 @@
     private final Bundle m_bundle;
 
     private List<BundleRevision> m_fragments = null;
-    private List<FelixBundleWire> m_wires = 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;
@@ -446,12 +449,7 @@
 
     public List<BundleWire> getRequiredWires(String namespace)
     {
-        return asBundleWires(m_wires);
-    }
-
-    private static List<BundleWire> asBundleWires(List<? extends BundleWire> l)
-    {
-        return (List<BundleWire>) l;
+        return m_wires;
     }
 
     public BundleRevision getRevision()
@@ -645,12 +643,55 @@
         return m_id;
     }
 
-    public synchronized List<FelixBundleWire> getWires()
+// 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 setWires(List<FelixBundleWire> 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(
+        List<ResolverWire> rws,
+        Map<ResolverWire, Set<String>> requiredPkgWires)
     {
         // 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
@@ -661,43 +702,122 @@
         // 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))
+        {
+            throw new IllegalStateException("The revision already has wires.");
+        }
+
+        // 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))
+            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))
+            else if (m_wires.get(i).getCapability().getNamespace()
+                .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
                     .removeDependentImporter(this);
             }
         }
 
-        m_wires = wires;
+        // 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.
-        for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
+        if (!isFragment && (rws != null))
         {
-            if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+            for (ResolverWire rw : rws)
             {
-// TODO: OSGi R4.3 - What's the correct way to handle this?
-//                ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-//                    .addDependentRequirer(this);
-                ((BundleRevisionImpl) ((FelixBundleWire)
-                    m_wires.get(i)).getProvider()).addDependentRequirer(this);
-            }
-            else if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-// TODO: OSGi R4.3 - What's the correct way to handle this?
-//                ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-//                    .addDependentImporter(this);
-                ((BundleRevisionImpl) ((FelixBundleWire)
-                    m_wires.get(i)).getProvider()).addDependentImporter(this);
+                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);
+                }
             }
         }
     }
@@ -939,7 +1059,7 @@
                 // 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(name, isClass);
+                result = searchImports(pkgName, name, isClass);
 
                 // If not found, try the revision's own class path.
                 if (result == null)
@@ -951,7 +1071,7 @@
                     // If still not found, then try the revision's dynamic imports.
                     if (result == null)
                     {
-                        result = searchDynamicImports(name, pkgName, isClass);
+                        result = searchDynamicImports(pkgName, name, isClass);
                     }
                 }
             }
@@ -1119,59 +1239,46 @@
             completeUrlList.add(urls);
         }
 
-        // Look in the module's imports.
-        // We delegate to the module's wires for the resources.
-        // If any resources are found, this means that the package of these
-        // resources is imported, we must not keep looking since we do not
-        // support split-packages.
-
-        // Note that the search may be aborted if this method throws an
-        // exception, otherwise it continues if a null is returned.
-        List<FelixBundleWire> wires = getWires();
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        // 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)
         {
-            if (wires.get(i).getRequirement().getNamespace()
-                .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+            // Delegate to the provider revision.
+            urls = ((BundleRevisionImpl) provider).getResourcesByDelegation(name);
+
+            // If we find any resources, then add them.
+            if ((urls != null) && (urls.hasMoreElements()))
             {
-                try
-                {
-                    // If we find the class or resource, then return it.
-                    urls = wires.get(i).getResources(name);
-                }
-                catch (ResourceNotFoundException ex)
-                {
-                    urls = null;
-                }
-                if (urls != null)
-                {
-                    completeUrlList.add(urls);
-                    return new CompoundEnumeration((Enumeration[])
-                        completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
-                }
+                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).
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        List<BundleRevision> providers = getRequiredPackageSources(pkgName);
+        if (providers != null)
         {
-            if (wires.get(i).getRequirement().getNamespace()
-                .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+            for (BundleRevision p : providers)
             {
-                try
-                {
-                    // If we find the class or resource, then add it.
-                    urls = wires.get(i).getResources(name);
-                }
-                catch (ResourceNotFoundException ex)
-                {
-                    urls = null;
-                }
-                if (urls != null)
+                // 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.
             }
         }
 
@@ -1189,26 +1296,21 @@
             // 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.
-            FelixBundleWire wire = null;
             try
             {
-                wire = m_resolver.resolve(this, pkgName);
+                provider = m_resolver.resolve(this, pkgName);
             }
             catch (ResolveException ex)
             {
                 // Ignore this since it is likely normal.
             }
-            if (wire != null)
+            if (provider != null)
             {
-                try
-                {
-                    urls = wire.getResources(name);
-                }
-                catch (ResourceNotFoundException ex)
-                {
-                    urls = null;
-                }
-                if (urls != 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);
                 }
@@ -1368,30 +1470,33 @@
         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.
-        for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
+        if (m_fragments != null)
         {
-            // If the fragment has no wires, then there is no reason to try to
-            // remove ourself from its wires since it has apparently already
-            // been refreshed.
-            if (((BundleRevisionImpl) m_fragments.get(i)).getWires() != null)
+            for (BundleRevision fragment : m_fragments)
             {
-                List<FelixBundleWire> hostWires = new ArrayList<FelixBundleWire>(
-                    ((BundleRevisionImpl) m_fragments.get(i)).getWires());
-                for (Iterator<FelixBundleWire> it = hostWires.iterator(); it.hasNext(); )
-                {
-                    FelixBundleWire hostWire = it.next();
-                    if (hostWire.getProviderWiring().getRevision().equals(this))
-                    {
-                        it.remove();
-                        ((BundleRevisionImpl) m_fragments.get(i)).setWires(hostWires);
-                        break;
-                    }
-                }
+                ((BundleRevisionImpl) fragment).detachHost(this);
             }
         }
 
@@ -1565,37 +1670,69 @@
         return parent;
     }
 
-    private Object searchImports(String name, boolean isClass)
+    private Object searchImports(String pkgName, String name, boolean isClass)
         throws ClassNotFoundException, ResourceNotFoundException
     {
-        // We delegate to the module's wires to find the class or resource.
-        List<FelixBundleWire> wires = getWires();
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        // 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) wires.get(i).getClass(name)
-                : (Object) wires.get(i).getResource(name);
+                ? (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 name, String pkgName, final boolean isClass)
+        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.
-        FelixBundleWire wire = null;
+        BundleRevision provider = null;
         try
         {
-            wire = m_resolver.resolve(this, pkgName);
+            provider = m_resolver.resolve(this, pkgName);
         }
         catch (ResolveException ex)
         {
@@ -1604,15 +1741,15 @@
 
         // If the dynamic import was successful, then this initial
         // time we must directly return the result from dynamically
-        // created wire, but subsequent requests for classes/resources
-        // in the associated package will be processed as part of
-        // normal static imports.
-        if (wire != null)
+        // 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) wire.getClass(name)
-                : (Object) wire.getResource(name);
+                ? (Object) ((BundleRevisionImpl) provider).getClassByDelegation(name)
+                : (Object) ((BundleRevisionImpl) provider).getResourceByDelegation(name);
         }
 
         // If implicit boot delegation is enabled, then try to guess whether
@@ -2362,7 +2499,7 @@
         String importer = revision.getBundle().toString();
 
         // Next, check to see if the revision imports the package.
-        List<FelixBundleWire> wires = revision.getWires();
+        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) &&
@@ -2462,14 +2599,14 @@
                 revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
             Set<BundleCapability> exporters = resolver.getCandidates(req, false);
 
-            FelixBundleWire wire = null;
+            BundleRevision provider = null;
             try
             {
-                wire = resolver.resolve(revision, pkgName);
+                provider = resolver.resolve(revision, pkgName);
             }
             catch (Exception ex)
             {
-                wire = null;
+                provider = null;
             }
 
             String exporter = (exporters.isEmpty())
@@ -2482,7 +2619,7 @@
             sb.append("' is dynamically imported by bundle ");
             sb.append(importer);
             sb.append(".");
-            if ((exporters.size() > 0) && (wire == null))
+            if ((exporters.size() > 0) && (provider == null))
             {
                 sb.append(" However, bundle ");
                 sb.append(exporter);
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 98b8183..db092bc 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -46,8 +46,6 @@
 import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
-import org.apache.felix.framework.wiring.FelixBundleWireImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -74,6 +72,7 @@
 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.service.packageadmin.ExportedPackage;
 import org.osgi.service.startlevel.StartLevel;
 
@@ -3480,15 +3479,13 @@
                 ((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentImporters();
             for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
             {
-                List<FelixBundleWire> wires =
-                    ((BundleRevisionImpl) dependents.get(depIdx)).getWires();
-                for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
+                BundleRevision providerRevision =
+                    ((BundleRevisionImpl) dependents.get(depIdx))
+                        .getImportedPackageSource(ep.getName());                
+                if ((providerRevision != null)
+                    && (providerRevision == expRevisions.get(expIdx)))
                 {
-                    if ((wires.get(wireIdx).getProviderWiring().getRevision() == expRevisions.get(expIdx))
-                        && (wires.get(wireIdx).hasPackage(ep.getName())))
-                    {
-                        list.add(dependents.get(depIdx).getBundle());
-                    }
+                    list.add(dependents.get(depIdx).getBundle());
                 }
             }
             dependents = ((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentRequirers();
@@ -4182,9 +4179,11 @@
             }
         }
 
-        FelixBundleWire resolve(BundleRevision revision, String pkgName) throws ResolveException
+        BundleRevision resolve(BundleRevision revision, String pkgName)
+            throws ResolveException
         {
-            FelixBundleWire candidateWire = null;
+            BundleRevision provider = null;
+
             // We cannot dynamically import if the revision is not already resolved
             // or if it is not allowed, so check that first. Note: We check if the
             // dynamic import is allowed without holding any locks, but this is
@@ -4207,41 +4206,33 @@
                     // 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.
-                    List<FelixBundleWire> wires = ((BundleRevisionImpl) revision).getWires();
-                    for (int i = 0; (wires != null) && (i < wires.size()); i++)
+                    provider = ((BundleRevisionImpl)revision)
+                        .getImportedPackageSource(pkgName);
+                    if (provider == null)
                     {
-                        if (wires.get(i).hasPackage(pkgName))
+                        wireMap = m_resolver.resolve(
+                            m_resolverState, revision, pkgName,
+                            m_resolverState.getFragments());
+
+                        if ((wireMap != null) && wireMap.containsKey(revision))
                         {
-                            return wires.get(i);
-                        }
-                    }
+                            List<ResolverWire> dynamicWires = wireMap.remove(revision);
+                            ResolverWire dynamicWire = dynamicWires.get(0);
 
-                    wireMap = m_resolver.resolve(
-                        m_resolverState, revision, pkgName, m_resolverState.getFragments());
+                            // Mark all revisions as resolved.
+                            markResolvedRevisions(wireMap);
 
-                    if ((wireMap != null) && wireMap.containsKey(revision))
-                    {
-                        List<ResolverWire> dynamicWires = wireMap.remove(revision);
-                        ResolverWire rw = dynamicWires.get(0);
-                        candidateWire = new FelixBundleWireImpl(
-                            rw.getRequirer(),
-                            rw.getRequirement(),
-                            rw.getProvider(),
-                            rw.getCapability());
+                            // Dynamically add new wire to importing revision.
+                            if (dynamicWire != null)
+                            {
+                                ((BundleRevisionImpl) revision).addDynamicWire(dynamicWire);
+                                m_logger.log(
+                                    Logger.LOG_DEBUG,
+                                    "DYNAMIC WIRE: " + dynamicWire);
 
-                        // Mark all revisions as resolved.
-                        markResolvedRevisions(wireMap);
-
-                        // Dynamically add new wire to importing revision.
-                        if (candidateWire != null)
-                        {
-                            wires = new ArrayList(wires.size() + 1);
-                            wires.addAll(((BundleRevisionImpl) revision).getWires());
-                            wires.add(candidateWire);
-                            ((BundleRevisionImpl) revision).setWires(wires);
-                            m_logger.log(
-                                Logger.LOG_DEBUG,
-                                "DYNAMIC WIRE: " + wires.get(wires.size() - 1));
+                                provider = ((BundleRevisionImpl) revision)
+                                    .getImportedPackageSource(pkgName);
+                            }
                         }
                     }
                 }
@@ -4254,7 +4245,7 @@
                 fireResolvedEvents(wireMap);
             }
 
-            return candidateWire;
+            return provider;
         }
 
         // This method duplicates a lot of logic from:
@@ -4287,14 +4278,12 @@
                     return false;
                 }
             }
-            // If any of our wires have this package, then we cannot
-            // attempt to dynamically import it.
-            for (FelixBundleWire w : ((BundleRevisionImpl) revision).getWires())
+
+            // If this revision already imports or requires this package, then
+            // we cannot dynamically import it.
+            if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
             {
-                if (w.hasPackage(pkgName))
-                {
-                    return false;
-                }
+                return false;
             }
 
             // Loop through the importer's dynamic requirements to determine if
@@ -4354,41 +4343,25 @@
                 {
                     BundleRevision revision = entry.getKey();
                     List<ResolverWire> resolverWires = entry.getValue();
-                    List<FelixBundleWire> wires = new ArrayList<FelixBundleWire>();
 
-                    // Convert resolver wires into bundle wires.
-                    for (Iterator<ResolverWire> itWires = resolverWires.iterator();
-                        itWires.hasNext(); )
+                    Map<ResolverWire, Set<String>> requiredPkgWires =
+                        new HashMap<ResolverWire, Set<String>>();
+                    for (ResolverWire rw : resolverWires)
                     {
-                        ResolverWire rw = itWires.next();
-                        if (!Util.isFragment(revision))
+                        if (rw.getCapability().getNamespace()
+                            .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
                         {
-                            m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
+                            Set<String> pkgs =
+                                calculateExportedAndReexportedPackages(
+                                    rw.getProvider(),
+                                    wireMap,
+                                    new HashSet<String>(),
+                                    new HashSet<BundleRevision>());
+                            requiredPkgWires.put(rw, pkgs);
                         }
-                        else
-                        {
-                            m_logger.log(
-                                Logger.LOG_DEBUG,
-                                "FRAGMENT WIRE: "
-                                + revision + " -> hosted by -> " + rw.getProvider());
-                        }
-                        wires.add(
-                            new FelixBundleWireImpl(
-                                rw.getRequirer(),
-                                rw.getRequirement(),
-                                rw.getProvider(),
-                                rw.getCapability()));
                     }
 
-                    // Set the revision's wires. If the revision is a resolved
-                    // fragment, then we must actually append any new host
-                    // wires to the existing ones, since fragments can be attached
-                    // to multiple hosts spanning multiple resolve operations.
-                    if (Util.isFragment(revision) && (revision.getWiring() != null))
-                    {
-                        wires.addAll(((BundleRevisionImpl) revision).getWires());
-                    }
-                    ((BundleRevisionImpl) revision).setWires(wires);
+                    ((BundleRevisionImpl) revision).setWires(resolverWires, requiredPkgWires);
 
                     // Attach fragments, if any.
                     List<BundleRevision> fragments = hosts.get(revision);
@@ -4407,7 +4380,7 @@
                                 revision = reentry.getKey();
 
                                 // Undo wires.
-                                ((BundleRevisionImpl) revision).setWires(null);
+                                ((BundleRevisionImpl) revision).setWires(null, null);
 
                                 fragments = hosts.get(revision);
                                 if (fragments != null)
@@ -4530,6 +4503,73 @@
         }
     }
 
+    private static Set<String> calculateExportedAndReexportedPackages(
+        BundleRevision br,
+        Map<BundleRevision, List<ResolverWire>> wireMap,
+        Set<String> pkgs,
+        Set<BundleRevision> cycles)
+    {
+        if (!cycles.contains(br))
+        {
+            cycles.add(br);
+
+            // Add all exported packages.
+            for (BundleCapability cap : br.getDeclaredCapabilities(null))
+            {
+                if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                {
+                    pkgs.add((String)
+                        cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+                }
+            }
+
+            // Now check to see if any required bundles are required with reexport
+            // visibility, since we need to include those packages too.
+            if (br.getWiring() == null)
+            {
+                for (ResolverWire rw : wireMap.get(br))
+                {
+                    if (rw.getCapability().getNamespace().equals(
+                        BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                    {
+                        String dir = rw.getRequirement()
+                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+                        {
+                            calculateExportedAndReexportedPackages(
+                                rw.getProvider(),
+                                wireMap,
+                                pkgs,
+                                cycles);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                for (BundleWire bw : br.getWiring().getRequiredWires(null))
+                {
+                    if (bw.getCapability().getNamespace().equals(
+                        BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                    {
+                        String dir = bw.getRequirement()
+                            .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                        if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+                        {
+                            calculateExportedAndReexportedPackages(
+                                bw.getProviderWiring().getRevision(),
+                                wireMap,
+                                pkgs,
+                                cycles);
+                        }
+                    }
+                }
+            }
+        }
+
+        return pkgs;
+    }
+
     class SystemBundleActivator implements BundleActivator
     {
         public void start(BundleContext context) throws Exception
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 3718642..f19531f 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -20,13 +20,13 @@
 
 import java.util.*;
 import org.apache.felix.framework.util.VersionRange;
-import org.apache.felix.framework.wiring.FelixBundleWire;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.service.packageadmin.RequiredBundle;
@@ -237,7 +237,7 @@
                 BundleRevisionImpl revision = (BundleRevisionImpl) revisions.get(modIdx);
                 if (revision.isResolved())
                 {
-                    List<FelixBundleWire> hostWires = revision.getWires();
+                    List<BundleWire> hostWires = revision.getWires();
                     for (int i = 0; (hostWires != null) && (i < hostWires.size()); i++)
                     {
                         Bundle b = hostWires.get(i).getProviderWiring().getBundle();
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 ff69464..b76ade8 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -35,12 +35,12 @@
 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.FelixBundleWire;
 import org.osgi.framework.BundlePermission;
 import org.osgi.framework.Constants;
 import org.osgi.framework.PackagePermission;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
 
 class ResolverStateImpl implements Resolver.ResolverState
 {
@@ -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 (FelixBundleWire w : ((BundleRevisionImpl) br).getWires())
+            for (BundleWire w : ((BundleRevisionImpl) br).getWires())
             {
                 if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
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 7cfb8cb..f544c4a 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -27,10 +27,10 @@
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
 import org.osgi.framework.*;
 import org.osgi.framework.BundleReference;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
 
 class ServiceRegistrationImpl implements ServiceRegistration
 {
@@ -487,10 +487,10 @@
                 Util.getClassPackage(className);
             BundleRevision requesterRevision = ((BundleImpl) requester).getCurrentRevision();
             // Get package wiring from service requester.
-            FelixBundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
+            BundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
             // Get package wiring from service provider.
             BundleRevision providerRevision = ((BundleImpl) m_bundle).getCurrentRevision();
-            FelixBundleWire providerWire = Util.getWire(providerRevision, pkgName);
+            BundleWire providerWire = Util.getWire(providerRevision, pkgName);
 
             // There are four situations that may occur here:
             //   1. Neither the requester, nor provider have wires for the package.
@@ -550,7 +550,8 @@
                         {
                             // If requester has access to the class, verify it is the
                             // same class as the provider.
-                            allow = (providerWire.getClass(className) == requestClass);
+                            allow = (((BundleRevisionImpl) providerRevision)
+                                .getClassByDelegation(className) == requestClass);
                         }
                         catch (Exception ex)
                         {
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 2d01768..c6d6a5c 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
@@ -356,6 +356,7 @@
                         {
                             hostReq = r;
                             it.remove();
+                            break;
                         }
                     }
 
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 9dc122d..829098e 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
@@ -34,11 +34,11 @@
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
 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;
 
 public class ResolverImpl implements Resolver
 {
@@ -376,14 +376,12 @@
                 return null;
             }
         }
-        // If any of our wires have this package, then we cannot
-        // attempt to dynamically import it.
-        for (FelixBundleWire w : ((BundleRevisionImpl) revision).getWires())
+
+        // If this revision already imports or requires this package, then
+        // we cannot dynamically import it.
+        if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
         {
-            if (w.hasPackage(pkgName))
-            {
-                return null;
-            }
+            return null;
         }
 
         // Loop through the importer's dynamic requirements to determine if
@@ -468,7 +466,7 @@
         if (revision.getWiring() != null)
         {
             // Use wires to get actual requirements and satisfying capabilities.
-            for (FelixBundleWire wire : ((BundleRevisionImpl) revision).getWires())
+            for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
             {
                 // Wrap the requirement as a hosted requirement
                 // if it comes from a fragment, since we will need
@@ -1173,7 +1171,7 @@
         // exports are substitutable.
         if (revision.getWiring() != null)
         {
-            for (FelixBundleWire wire : ((BundleRevisionImpl) revision).getWires())
+            for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
             {
                 if (wire.getRequirement().getNamespace().equals(
                     BundleCapabilityImpl.PACKAGE_NAMESPACE))
@@ -1350,14 +1348,15 @@
                 if ((cands != null) && (cands.size() > 0))
                 {
                     BundleCapability cand = cands.iterator().next();
-                    if (cand.getRevision().getWiring() == null)
-                    {
-                        populateWireMap(cand.getRevision(),
-                            revisionPkgMap, wireMap, allCandidates);
-                    }
                     // Ignore revisions that import themselves.
                     if (!revision.equals(cand.getRevision()))
                     {
+                        if (cand.getRevision().getWiring() == null)
+                        {
+                            populateWireMap(cand.getRevision(),
+                                revisionPkgMap, wireMap, allCandidates);
+                        }
+                        Packages candPkgs = revisionPkgMap.get(cand.getRevision());
                         ResolverWire wire = new ResolverWireImpl(
                             unwrappedRevision,
                             (BundleRequirementImpl) getActualRequirement(req),
@@ -1428,6 +1427,7 @@
                             allCandidates);
                     }
 
+                    Packages candPkgs = revisionPkgMap.get(blame.m_cap.getRevision());
                     Map<String, Object> attrs = new HashMap(1);
                     attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
                     packageWires.add(
@@ -1595,44 +1595,6 @@
         {
             m_revision = revision;
         }
-
-        public List<String> getExportedAndReexportedPackages()
-        {
-            List<String> pkgs = new ArrayList();
-            // Grab the revision's actual exported packages.
-            // Note that we ignore the calculated exported packages here,
-            // because bundles that import their own exports still continue
-            // to provide access to their exports when they are required; i.e.,
-            // the implicitly reexport the packages if wired to another provider.
-            List<BundleCapability> caps = (m_revision.getWiring() != null)
-                ? m_revision.getWiring().getCapabilities(null)
-                : m_revision.getDeclaredCapabilities(null);
-            for (BundleCapability cap : caps)
-            {
-                if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                {
-                    pkgs.add((String)
-                        cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
-                }
-            }
-            // Grab all required and reexported required packages.
-            for (Entry<String, List<Blame>> entry : m_requiredPkgs.entrySet())
-            {
-                for (Blame blame : entry.getValue())
-                {
-                    String value = blame.m_reqs.get(
-                        blame.m_reqs.size() - 1).getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                    if ((value != null)
-                        && value.equals(Constants.VISIBILITY_REEXPORT))
-                    {
-                        pkgs.add((String)
-                            blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
-                        break;
-                    }
-                }
-            }
-            return pkgs;
-        }
     }
 
     private static class Blame
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
index 69162b9..324c6df 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.framework.resolver;
 
+import java.util.Set;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
index 7a51877..d89012e 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.felix.framework.resolver;
 
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
@@ -31,7 +29,8 @@
     private final BundleRevision m_provider;
     private final BundleCapability m_cap;
 
-    public ResolverWireImpl(BundleRevision requirer, BundleRequirement req,
+    public ResolverWireImpl(
+        BundleRevision requirer, BundleRequirement req,
         BundleRevision provider, BundleCapability cap)
     {
         m_requirer = requirer;
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 38f8ecf..817ad66 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
@@ -31,12 +31,12 @@
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
 
 public class Util
 {
@@ -327,15 +327,17 @@
         return matching;
     }
 
-    public static FelixBundleWire getWire(BundleRevision br, String name)
+    public static BundleWire getWire(BundleRevision br, String name)
     {
-        List<FelixBundleWire> wires = ((BundleRevisionImpl) br).getWires();
+        List<BundleWire> wires = ((BundleRevisionImpl) br).getWires();
         if (wires != null)
         {
-            for (FelixBundleWire w : wires)
+            for (BundleWire w : wires)
             {
-                if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
-                    w.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+                if (w.getCapability().getNamespace()
+                        .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                    w.getCapability().getAttributes()
+                        .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
                 {
                     return w;
                 }
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
new file mode 100644
index 0000000..2909b0a
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
@@ -0,0 +1,71 @@
+/*
+ * 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.wiring;
+
+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;
+
+// TODO: OSGi R4.3 - Should this be in framework package?
+public class BundleWireImpl implements BundleWire
+{
+    private final BundleRevision m_requirer;
+    private final BundleRequirement m_req;
+    private final BundleRevision m_provider;
+    private final BundleCapability m_cap;
+
+    public BundleWireImpl(BundleRevision requirer, BundleRequirement req,
+        BundleRevision provider, BundleCapability cap)
+    {
+        m_requirer = requirer;
+        m_req = req;
+        m_provider = provider;
+        m_cap = cap;
+    }
+
+    public BundleWiring getRequirerWiring()
+    {
+        return m_requirer.getWiring();
+    }
+
+    public BundleRequirement getRequirement()
+    {
+        return m_req;
+    }
+
+    public BundleWiring getProviderWiring()
+    {
+        return m_provider.getWiring();
+    }
+
+    public BundleCapability getCapability()
+    {
+        return m_cap;
+    }
+
+    public String toString()
+    {
+        return "[" + m_requirer + "] "
+            + m_req
+            + " -> "
+            + "[" + m_provider + "]";
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java b/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java
deleted file mode 100644
index 539e24b..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.wiring;
-
-import java.net.URL;
-import java.util.Enumeration;
-import org.apache.felix.framework.resolver.ResourceNotFoundException;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-
-public interface FelixBundleWire extends BundleWire
-{
-    public BundleRevision getRequirer();
-
-    public BundleRevision getProvider();
-
-    /**
-     * Returns whether or not the wire has a given package name. For some
-     * wires, such as ones for Require-Bundle, there may be many packages.
-     * This method is necessary since the set of packages attained by wires
-     * restrict which packages can be dynamically imported (i.e., you cannot
-     * dynamically import a package that is already attainable from an
-     * existing wire).
-     * @return <tt>true</tt> if the package name is attainable from this wire,
-     *         <tt>false</tt> otherwise.
-    **/
-    boolean hasPackage(String pkgName);
-    /**
-     * Requests a class from the exporting module. If the class is found, then
-     * it is returned. If the class is not found, then this method may or may
-     * not throw an exception depending on the wire type (e.g., for an
-     * imported package or a required bundle). Throwing an exception indicates
-     * that the search should be aborted, while returning a <tt>null</tt>
-     * indicates that the search should continue.
-     * @return The class if found or <tt>null</tt> if not found and the search
-     *         should continue.
-     * @throws java.lang.ClassNotFoundException If the class was not found and
-     *         the search should be aborted.
-    **/
-    Class getClass(String name) throws ClassNotFoundException;
-    /**
-     * Requests a resource from the exporting module. If the resource is found,
-     * then an URL is returned. If the resource is not found, then this method may
-     * or may not throw an exception depending on the wire type (e.g., for an
-     * imported package or a required bundle). Throwing an exception indicates
-     * that the search should be aborted, while returning a <tt>null</tt>
-     * indicates that the search should continue.
-     * @return An URL to the resource if found or <tt>null</tt> if not found
-     *         and the search should continue.
-     * @throws ResourceNotFoundException If the resource was not found and
-     *         the search should be aborted.
-    **/
-    URL getResource(String name) throws ResourceNotFoundException;
-    /**
-     * Requests resources from the exporting module. If the resources are found,
-     * then an enumeration of URLs is returned. If the resources are not found,
-     * then this method may or may not throw an exception depending on the wire
-     * type (e.g., for an imported package or a required bundle). Throwing an
-     * exception indicates that the search should be aborted, while returning a
-     * <tt>null</tt> indicates that the search should continue.
-     * @return An enumeration of URLs for the resource if found or <tt>null</tt>
-     *         if not found and the search should continue.
-     * @throws ResourceNotFoundException If the resource was not found and
-     *         the search should be aborted.
-    **/
-    Enumeration getResources(String name) throws ResourceNotFoundException;
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java
deleted file mode 100644
index c075a02..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.wiring;
-
-import org.apache.felix.framework.resolver.*;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.util.Util;
-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;
-
-// TODO: OSGi R4.3 - Should this be in framework package?
-public class FelixBundleWireImpl implements FelixBundleWire
-{
-    private final BundleRevision m_requirer;
-    private final BundleRequirement m_req;
-    private final BundleRevision m_provider;
-    private final BundleCapability m_cap;
-    private volatile Set<String> m_packages;
-
-    public FelixBundleWireImpl(BundleRevision requirer, BundleRequirement req,
-        BundleRevision provider, BundleCapability cap)
-    {
-        m_requirer = requirer;
-        m_req = req;
-        m_provider = provider;
-        m_cap = cap;
-    }
-
-    public BundleRevision getRequirer()
-    {
-        return m_requirer;
-    }
-
-    public BundleWiring getRequirerWiring()
-    {
-        return m_requirer.getWiring();
-    }
-
-    public BundleRequirement getRequirement()
-    {
-        return m_req;
-    }
-
-    public BundleRevision getProvider()
-    {
-        return m_provider;
-    }
-
-    public BundleWiring getProviderWiring()
-    {
-        return m_provider.getWiring();
-    }
-
-    public BundleCapability getCapability()
-    {
-        return m_cap;
-    }
-
-    public String toString()
-    {
-        return "[" + m_requirer + "] "
-            + m_req
-            + " -> "
-            + "[" + m_provider + "]";
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
-     */
-    public boolean hasPackage(String pkgName)
-    {
-        boolean result = false;
-        if (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-        {
-            result = m_cap.getAttributes()
-                .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName); 
-        }
-        else if (m_cap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-        {
-            if (m_packages == null)
-            {
-                m_packages = calculateRequiredPackages(
-                    m_provider.getWiring(), new HashSet<String>());
-            }
-            result = m_packages.contains(pkgName);
-        }
-        return result;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
-     */
-    public Class getClass(String name) throws ClassNotFoundException
-    {
-        Class clazz = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getClassPackage(name);
-
-        // Only check if this wire provides the target package.
-        if (hasPackage(pkgName))
-        {
-            String namespace = m_cap.getNamespace();
-            if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-                // Check the include/exclude filters from the target package
-                // to make sure that the class is actually visible. We delegate
-                // to the exporting revision, rather than its content, so it can
-                // it can follow any internal wires it may have (e.g., if the
-                // package has multiple sources).
-                if (((BundleCapabilityImpl) m_cap).isIncluded(name))
-                {
-                    clazz = ((BundleRevisionImpl) m_provider).getClassByDelegation(name);
-                }
-
-                // If no class was found, then we must throw an exception
-                // since the exporter for this package did not contain the
-                // requested class.
-                if (clazz == null)
-                {
-                    throw new ClassNotFoundException(name);
-                }
-            }
-            else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-            {
-                try
-                {
-                    clazz = ((BundleRevisionImpl) m_provider).getClassByDelegation(name);
-                }
-                catch (ClassNotFoundException ex)
-                {
-                    // Do not throw the exception here, since we want
-                    // to continue search other package sources and
-                    // ultimately the revision's own content.
-                }
-            }
-        }
-
-        return clazz;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
-     */
-    public URL getResource(String name) throws ResourceNotFoundException
-    {
-        URL url = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getResourcePackage(name);
-
-        // Only check if this wire provides the target package.
-        if (hasPackage(pkgName))
-        {
-            String namespace = m_cap.getNamespace();
-            if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-                // Delegate to the exporting revision, rather than its
-                // content, so that it can follow any internal wires it may have
-                // (e.g., if the package has multiple sources).
-                url = ((BundleRevisionImpl) m_provider).getResourceByDelegation(name);
-
-                // If no resource was found, then we must throw an exception
-                // since the exporter for this package did not contain the
-                // requested class.
-                if (url == null)
-                {
-                    throw new ResourceNotFoundException(name);
-                }
-            }
-            else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-            {
-                url = ((BundleRevisionImpl) m_provider).getResourceByDelegation(name);
-
-                // Don't throw ResourceNotFoundException because require-bundle
-                // dependencies support split packages.
-            }
-
-        }
-
-        return url;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
-     */
-    public Enumeration getResources(String name) throws ResourceNotFoundException
-    {
-        Enumeration urls = null;
-
-        // Get the package of the target class.
-        String pkgName = Util.getResourcePackage(name);
-
-        // Only check if this wire provides the target package.
-        if (hasPackage(pkgName))
-        {
-            String namespace = m_cap.getNamespace();
-            if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-                urls = ((BundleRevisionImpl) m_provider).getResourcesByDelegation(name);
-
-                // If no resource was found, then we must throw an exception
-                // since the exporter for this package did not contain the
-                // requested class.
-                if ((urls == null) || !urls.hasMoreElements())
-                {
-                    throw new ResourceNotFoundException(name);
-                }
-            }
-            else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-            {
-                urls = ((BundleRevisionImpl) m_provider).getResourcesByDelegation(name);
-
-                // Don't throw ResourceNotFoundException because require-bundle
-                // dependencies support split packages.
-            }
-        }
-
-        return urls;
-    }
-
-    private static Set<String> calculateRequiredPackages(
-        BundleWiring providerWiring, Set<String> packages)
-    {
-// TODO: OSGi R4.3 - This might be calcualted differently when BundleWiring
-//       returns the proper information.
-
-        // Add exported packages.
-        for (BundleCapability cap : providerWiring.getCapabilities(null))
-        {
-            if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
-            {
-                packages.add(
-                    (String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
-            }
-        }
-
-        // Add re-exported packages for any required bundle dependencies
-        // that are re-exported.
-        for (BundleWire bw : providerWiring.getRequiredWires(null))
-        {
-            if (bw.getRequirement().getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
-            {
-                String dir =
-                    bw.getRequirement().getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
-                if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
-                {
-                    calculateRequiredPackages(bw.getProviderWiring(), packages);
-                }
-            }
-        }
-        return packages;
-    }
-}
\ No newline at end of file