Move dependency bookkeeping out of BundleRevisionImpl to try to clean
up design. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102831 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 88bfd9d..4ed25da 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -96,6 +96,7 @@
         return m_archive;
     }
 
+// Only called when the framework is stopping. Don't need to clean up dependencies.
     synchronized void close()
     {
         closeRevisions();
@@ -112,6 +113,9 @@
         }
     }
 
+// Called when install fails, when stopping framework with uninstalled bundles,
+// and when refreshing an uninstalled bundle. Only need to clear up dependencies
+// for last case.
     synchronized void closeAndDelete() throws Exception
     {
         // Mark the bundle as stale, since it is being deleted.
@@ -122,6 +126,7 @@
         m_archive.closeAndDelete();
     }
 
+// Called from BundleImpl.close(), BundleImpl.closeAndDelete(), and BundleImpl.refresh()
     private void closeRevisions()
     {
         // Remove the bundle's associated revisions from the resolver state
@@ -136,6 +141,7 @@
         }
     }
 
+// Called when refreshing a bundle. Must clean up dependencies beforehand.
     synchronized void refresh() throws Exception
     {
         if (isExtension() && (getFramework().getState() != Bundle.STOPPING))
@@ -1048,35 +1054,6 @@
         return m_revisions.get(m_revisions.size() - 1);
     }
 
-    synchronized boolean isUsed()
-    {
-        boolean unresolved = true;
-        for (int i = 0; unresolved && (i < m_revisions.size()); i++)
-        {
-            if (m_revisions.get(i).getWiring() != null)
-            {
-                unresolved = false;
-            }
-        }
-        boolean used = false;
-        for (int i = 0; !unresolved && !used && (i < m_revisions.size()); i++)
-        {
-            if (m_revisions.get(i).getWiring() != null)
-            {
-                List<BundleRevision> dependents =
-                    ((BundleRevisionImpl) m_revisions.get(i)).getDependents();
-                for (int j = 0; (dependents != null) && (j < dependents.size()) && !used; j++)
-                {
-                    if (dependents.get(j) != m_revisions.get(i))
-                    {
-                        used = true;
-                    }
-                }
-            }
-        }
-        return used;
-    }
-
     synchronized void revise(String location, InputStream is)
         throws Exception
     {
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
new file mode 100644
index 0000000..72c28ad
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+class BundleRevisionDependencies
+{
+    private final Map<BundleRevision, Map<BundleCapability, Set<BundleRevision>>>
+        m_dependentsMap = new HashMap<BundleRevision, Map<BundleCapability, Set<BundleRevision>>>();
+
+    public synchronized void addDependent(BundleRevision provider, BundleCapability cap, BundleRevision requirer)
+    {
+        Map<BundleCapability, Set<BundleRevision>> caps = m_dependentsMap.get(provider);
+        if (caps == null)
+        {
+            caps = new HashMap<BundleCapability, Set<BundleRevision>>();
+            m_dependentsMap.put(provider, caps);
+        }
+        Set<BundleRevision> dependents = caps.get(cap);
+        if (dependents == null)
+        {
+            dependents = new HashSet<BundleRevision>();
+            caps.put(cap, dependents);
+        }
+        dependents.add(requirer);
+    }
+
+    public synchronized void removeDependent(
+        BundleRevision provider, BundleCapability cap, BundleRevision requirer)
+    {
+        Map<BundleCapability, Set<BundleRevision>> caps = m_dependentsMap.get(provider);
+        if (caps != null)
+        {
+            Set<BundleRevision> dependents = caps.get(cap);
+            if (dependents == null)
+            {
+                dependents.remove(requirer);
+                if (dependents.isEmpty())
+                {
+                    caps.remove(cap);
+                    if (caps.isEmpty())
+                    {
+                        m_dependentsMap.remove(provider);
+                    }
+                }
+            }
+        }
+    }
+
+    public synchronized void removeDependents(BundleRevision provider)
+    {
+        m_dependentsMap.remove(provider);
+    }
+
+    public synchronized Map<BundleCapability, Set<BundleRevision>>
+        getDependents(BundleRevision provider)
+    {
+        return m_dependentsMap.get(provider);
+    }
+
+    public synchronized boolean hasDependents(BundleImpl bundle)
+    {
+        List<BundleRevision> revisions = bundle.getRevisions();
+        for (BundleRevision revision : revisions)
+        {
+            if (m_dependentsMap.containsKey(revision))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public synchronized Set<Bundle> getDependentBundles(BundleImpl bundle)
+    {
+        Set<Bundle> result = new HashSet<Bundle>();
+
+        List<BundleRevision> revisions = bundle.getRevisions();
+        for (BundleRevision revision : revisions)
+        {
+// TODO: OSGi R4.3 - This is sort of a hack. We need to special case fragments,
+//       since their dependents are their hosts.
+            if (Util.isFragment(revision))
+            {
+                if (revision.getWiring() != null)
+                {
+                    for (BundleWire wire : revision.getWiring().getRequiredWires(null))
+                    {
+                        result.add(wire.getProviderWiring().getBundle());
+                    }
+                }
+            }
+            else
+            {
+                Map<BundleCapability, Set<BundleRevision>> caps =
+                    m_dependentsMap.get(revision);
+                if (caps != null)
+                {
+                    for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
+                    {
+                        for (BundleRevision rev : entry.getValue())
+                        {
+                            result.add(rev.getBundle());
+                        }
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public synchronized Set<Bundle> getImportingBundles(
+        BundleImpl exporter, BundleCapability exportCap)
+    {
+        // Create set for storing importing bundles.
+        Set<Bundle> result = new HashSet<Bundle>();
+
+        // Get exported package name.
+        String pkgName = (String)
+            exportCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+
+        // Get all importers and requirers for all revisions of the bundle.
+        // The spec says that require-bundle should be returned with importers.
+        for (BundleRevision revision : exporter.getRevisions())
+        {
+            Map<BundleCapability, Set<BundleRevision>>
+                caps = m_dependentsMap.get(revision);
+            if (caps != null)
+            {
+                for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
+                {
+                    BundleCapability cap = entry.getKey();
+                    if ((cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                        && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
+                            .equals(pkgName))
+                        || cap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                    {
+                        for (BundleRevision dependent : entry.getValue())
+                        {
+                            result.add(dependent.getBundle());
+                        }
+                    }
+                }
+            }
+        }
+
+        // Return the results.
+        return result;
+    }
+
+    public synchronized Set<Bundle> getRequiringBundles(BundleImpl bundle)
+    {
+        // Create set for storing requiring bundles.
+        Set<Bundle> result = new HashSet<Bundle>();
+
+        // Get all requirers for all revisions of the bundle.
+        for (BundleRevision revision : bundle.getRevisions())
+        {
+            Map<BundleCapability, Set<BundleRevision>>
+                caps = m_dependentsMap.get(revision);
+            if (caps != null)
+            {
+                for (Entry<BundleCapability, Set<BundleRevision>> entry : caps.entrySet())
+                {
+                    if (entry.getKey().getNamespace()
+                        .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                    {
+                        for (BundleRevision dependent : entry.getValue())
+                        {
+                            result.add(dependent.getBundle());
+                        }
+                    }
+                }
+            }
+        }
+
+        // Return the results.
+        return result;
+    }
+
+    public synchronized void removeDependencies(BundleImpl bundle)
+    {
+        List<BundleRevision> revs = bundle.getRevisions();
+        for (BundleRevision rev : revs)
+        {
+            BundleWiring wiring = rev.getWiring();
+            if (wiring != null)
+            {
+                for (BundleWire wire : wiring.getRequiredWires(null))
+                {
+                    // The provider wiring may already be null if the framework
+                    // is shutting down, so don't worry about updating dependencies
+                    // in that case.
+                    if (wire.getProviderWiring() != null)
+                    {
+                        Map<BundleCapability, Set<BundleRevision>> caps =
+                            m_dependentsMap.get(wire.getProviderWiring().getRevision());
+                        if (caps != null)
+                        {
+                            List<BundleCapability> gc = new ArrayList<BundleCapability>();
+                            for (Entry<BundleCapability, Set<BundleRevision>> entry
+                                : caps.entrySet())
+                            {
+                                entry.getValue().remove(rev);
+                                if (entry.getValue().isEmpty())
+                                {
+                                    gc.add(entry.getKey());
+                                }
+                            }
+                            for (BundleCapability cap : gc)
+                            {
+                                caps.remove(cap);
+                            }
+                            if (caps.isEmpty())
+                            {
+                                m_dependentsMap.remove(wire.getProviderWiring().getRevision());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public synchronized void dump()
+    {
+/*
+System.out.println("DEPENDENTS:");
+        for (Entry<BundleRevision, Map<BundleCapability, Set<BundleRevision>>> entry
+            : m_dependentsMap.entrySet())
+        {
+            System.out.println("Revision " + entry.getKey() + " DEPS:");
+            for (Entry<BundleCapability, Set<BundleRevision>> capEntry : entry.getValue().entrySet())
+            {
+                System.out.println("   " + capEntry.getKey() + " <-- " + capEntry.getValue());
+            }
+        }
+*/
+    }
+}
\ No newline at end of file
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 1813617..33ecf5e 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -20,52 +20,29 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLStreamHandler;
-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.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.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.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.Version;
 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 BundleRevisionImpl implements BundleRevision
@@ -96,9 +73,6 @@
 
     private final Bundle m_bundle;
 
-    private List<BundleRevision> m_dependentImporters = new ArrayList<BundleRevision>(0);
-    private List<BundleRevision> m_dependentRequirers = new ArrayList<BundleRevision>(0);
-
     private Content[] m_contentPath;
     private boolean m_isActivationTriggered = false;
     private ProtectionDomain m_protectionDomain = null;
@@ -362,28 +336,17 @@
         return m_id;
     }
 
-    public synchronized void resolve(
-        List<BundleRevision> fragments,
-        List<ResolverWire> rws,
-        Map<ResolverWire, Set<String>> requiredPkgWires)
-        throws Exception
+    public synchronized void resolve(BundleWiringImpl wiring)
     {
-        // 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.
-
-        // If there is an existing wiring, then dispose of it, which will
-        // remove any dependencies on other wirings.
         if (m_wiring != null)
         {
             m_wiring.dispose();
             m_wiring = null;
         }
 
-        if (rws != null)
+        if (wiring != null)
         {
-            m_wiring = new BundleWiringImpl(
-                m_logger, m_configMap, m_resolver, this, fragments, rws, requiredPkgWires);
+            m_wiring = wiring;
         }
     }
 
@@ -684,70 +647,11 @@
         return null;
     }
 
-    public synchronized List<BundleRevision> getDependentImporters()
-    {
-        return m_dependentImporters;
-    }
-
-    public synchronized void addDependentImporter(BundleRevision br)
-    {
-        if (!m_dependentImporters.contains(br))
-        {
-            m_dependentImporters.add(br);
-        }
-    }
-
-    public synchronized void removeDependentImporter(BundleRevision br)
-    {
-        m_dependentImporters.remove(br);
-    }
-
-    public synchronized List<BundleRevision> getDependentRequirers()
-    {
-        return m_dependentRequirers;
-    }
-
-    public synchronized void addDependentRequirer(BundleRevision br)
-    {
-        if (!m_dependentRequirers.contains(br))
-        {
-            m_dependentRequirers.add(br);
-        }
-    }
-
-    public synchronized void removeDependentRequirer(BundleRevision br)
-    {
-        m_dependentRequirers.remove(br);
-    }
-
-    public synchronized List<BundleRevision> getDependents()
-    {
-        List<BundleRevision> dependents;
-        if (Util.isFragment(this))
-        {
-            dependents = new ArrayList<BundleRevision>();
-            List<BundleWire> wires = (m_wiring == null)
-                ? null : m_wiring.getRequiredWires(null);
-            for (int i = 0; (wires != null) && (i < wires.size()); i++)
-            {
-                dependents.add(wires.get(i).getProviderWiring().getRevision());
-            }
-        }
-        else
-        {
-            dependents = new ArrayList<BundleRevision>
-                (m_dependentImporters.size() + m_dependentRequirers.size());
-            dependents.addAll(m_dependentImporters);
-            dependents.addAll(m_dependentRequirers);
-        }
-        return dependents;
-    }
-
-    public synchronized void close()
+    synchronized void close()
     {
         try
         {
-            resolve(null, null, null);
+            resolve(null);
         }
         catch (Exception ex)
         {
@@ -783,4 +687,4 @@
         }
         return url;
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index db4c8cd..5b193e3 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -45,7 +45,6 @@
 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;
@@ -139,76 +138,18 @@
     BundleWiringImpl(
         Logger logger, Map configMap, StatefulResolver resolver,
         BundleRevisionImpl revision, List<BundleRevision> fragments,
-        List<ResolverWire> resolverWires,
-        Map<ResolverWire, Set<String>> requiredPkgWires)
+        List<BundleWire> wires,
+        Map<String, BundleRevision> importedPkgs,
+        Map<String, List<BundleRevision>> requiredPkgs)
         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;
+        m_requiredPkgs = requiredPkgs;
+        m_wires = wires;
 
         // 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
@@ -367,28 +308,6 @@
 
     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();
@@ -579,21 +498,12 @@
         return m_wires;
     }
 
-    public synchronized void addDynamicWire(ResolverWire rw)
+    public synchronized void addDynamicWire(BundleWireImpl wire)
     {
-        // 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());
+            wire.getProviderWiring().getRevision());
     }
 
     public BundleRevision getRevision()
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 7e039c7..5fee892 100644
--- a/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
+++ b/framework/src/main/java/org/apache/felix/framework/EntryFilterEnumeration.java
@@ -43,11 +43,13 @@
     {
         m_bundle = bundle;
         BundleRevision br = m_bundle.getCurrentRevision();
-        List<BundleRevision> fragments = ((BundleWiringImpl) br.getWiring()).getFragments();
-        if (includeFragments && (fragments != null))
+        if (includeFragments
+            && (br.getWiring() != null)
+            && (((BundleWiringImpl) br.getWiring()).getFragments() != null))
         {
-            m_revisions = new ArrayList(fragments.size() + 1);
-            m_revisions.addAll(fragments);
+            m_revisions = new ArrayList(
+                ((BundleWiringImpl) br.getWiring()).getFragments().size() + 1);
+            m_revisions.addAll(((BundleWiringImpl) br.getWiring()).getFragments());
         }
         else
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
index 0275069..01fab7a 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
@@ -18,7 +18,7 @@
  */
 package org.apache.felix.framework;
 
-import java.util.List;
+import java.util.Set;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
@@ -65,8 +65,8 @@
         {
             return null;
         }
-        List<Bundle> list = m_felix.getImportingBundles(this);
-        return list.toArray(new Bundle[list.size()]);
+        Set<Bundle> set = m_felix.getImportingBundles(m_exportingBundle, m_export);
+        return set.toArray(new Bundle[set.size()]);
     }
 
     public String getName()
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 be07bbc..cdae317 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -56,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.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
 
 /**
@@ -720,12 +721,17 @@
         }
 
         @Override
-        public void resolve(
-            List<BundleRevision> fragments, List<ResolverWire> rws,
-            Map<ResolverWire, Set<String>> requiredPkgWires) throws Exception
+        public void resolve(BundleWiringImpl wire)
         {
-            m_wiring = new ExtensionManagerWiring(
-                m_logger, m_configMap, null, this, fragments, rws, requiredPkgWires);
+            try
+            {
+                m_wiring = new ExtensionManagerWiring(
+                    m_logger, m_configMap, this);
+            }
+            catch (Exception ex)
+            {
+                // This should never happen.
+            }
         }
 
         @Override
@@ -738,14 +744,11 @@
     class ExtensionManagerWiring extends BundleWiringImpl
     {
         ExtensionManagerWiring(
-            Logger logger, Map configMap, StatefulResolver resolver,
-            BundleRevisionImpl revision, List<BundleRevision> fragments,
-            List<ResolverWire> resolverWires,
-            Map<ResolverWire, Set<String>> requiredPkgWires)
+            Logger logger, Map configMap, BundleRevisionImpl revision)
             throws Exception
         {
-            super(logger, configMap, resolver, revision,
-                fragments, resolverWires, requiredPkgWires);
+            super(logger, configMap, null, revision,
+                null, Collections.EMPTY_LIST, null, null);
         }
 
         @Override
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 4889fa5..079c1e9 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -46,6 +46,7 @@
 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.BundleWireImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -125,6 +126,9 @@
     // CONCURRENCY: Access guarded by the global lock for writes,
     // but no lock for reads since it is copy on write.
     private volatile List<BundleImpl> m_uninstalledBundles;
+    // Object to keep track of dependencies among bundle revisions.
+    private final BundleRevisionDependencies m_dependencies =
+        new BundleRevisionDependencies();
 
     // Framework's active start level.
     private volatile int m_activeStartLevel = FelixConstants.FRAMEWORK_INACTIVE_STARTLEVEL;
@@ -2146,7 +2150,8 @@
                 {
                     try
                     {
-                        if (!bundle.isUsed() && !bundle.isExtension())
+                        if (!m_dependencies.hasDependents(bundle)
+                            && !bundle.isExtension())
                         {
                             try
                             {
@@ -2486,7 +2491,7 @@
             {
                 // If the bundle is not used by anyone, then garbage
                 // collect it now.
-                if (!bundle.isUsed())
+                if (!m_dependencies.hasDependents(bundle))
                 {
                     try
                     {
@@ -3462,72 +3467,16 @@
         }
     }
 
-    List<Bundle> getDependentBundles(BundleImpl exporter)
+    // Needed by ExportedPackageImpl.
+    Set<Bundle> getImportingBundles(BundleImpl exporter, BundleCapability cap)
     {
-        // Create list for storing importing bundles.
-        List<Bundle> list = new ArrayList();
-
-        // Get all dependent revisions from all exporter revisions.
-        List<BundleRevision> revisions = exporter.getRevisions();
-        for (int revIdx = 0; revIdx < revisions.size(); revIdx++)
-        {
-            List<BundleRevision> dependents =
-                ((BundleRevisionImpl) revisions.get(revIdx)).getDependents();
-            for (int depIdx = 0;
-                (dependents != null) && (depIdx < dependents.size());
-                depIdx++)
-            {
-                list.add(dependents.get(depIdx).getBundle());
-            }
-        }
-
-        return list;
+        return m_dependencies.getImportingBundles(exporter, cap);
     }
 
-    List<Bundle> getImportingBundles(ExportedPackage ep)
+    // Needed by RequiredBundleImpl.
+    Set<Bundle> getRequiringBundles(BundleImpl bundle)
     {
-        // Create list for storing importing bundles.
-        List<Bundle> list = new ArrayList();
-
-        // Get exporting bundle information.
-        BundleImpl exporter = (BundleImpl) ep.getExportingBundle();
-
-        // Get all importers and requirers for all revisions of the bundle.
-        // The spec says that require-bundle should be returned with importers.
-        List<BundleRevision> expRevisions = exporter.getRevisions();
-        for (int expIdx = 0; (expRevisions != null) && (expIdx < expRevisions.size()); expIdx++)
-        {
-            // Include any importers that have wires to the specific
-            // exported package.
-            if (expRevisions.get(expIdx).getWiring() != null)
-            {
-                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());
-                }
-            }
-        }
-
-        // Return the results.
-        return list;
+        return m_dependencies.getRequiringBundles(bundle);
     }
 
     boolean resolveBundles(Bundle[] targets)
@@ -3671,18 +3620,18 @@
         {
             // Create map of bundles that import the packages
             // from the target bundles.
-            Map map = new HashMap();
+            Set<Bundle> set = new HashSet<Bundle>();
             for (int targetIdx = 0; targetIdx < newTargets.length; targetIdx++)
             {
                 // Add the current target bundle to the map of
                 // bundles to be refreshed.
                 BundleImpl target = (BundleImpl) newTargets[targetIdx];
-                map.put(target, target);
+                set.add(target);
                 // Add all importing bundles to map.
-                populateDependentGraph(target, map);
+                populateDependentGraph(target, set);
             }
 
-            bundles = (BundleImpl[]) map.values().toArray(new BundleImpl[map.size()]);
+            bundles = (BundleImpl[]) set.toArray(new BundleImpl[set.size()]);
         }
 
         // Now refresh each bundle.
@@ -3776,23 +3725,23 @@
         fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this, null);
     }
 
-    private void populateDependentGraph(BundleImpl exporter, Map map)
+    private void populateDependentGraph(BundleImpl exporter, Set<Bundle> set)
     {
         // Get all dependent bundles of this bundle.
-        List<Bundle> dependents = getDependentBundles(exporter);
+        Set<Bundle> dependents = m_dependencies.getDependentBundles(exporter);
 
-        for (int depIdx = 0;
-            (dependents != null) && (depIdx < dependents.size());
-            depIdx++)
+        if (dependents != null)
         {
-            // Avoid cycles if the bundle is already in map.
-            if (!map.containsKey(dependents.get(depIdx)))
+            for (Bundle b : dependents)
             {
-                // Add each importing bundle to map.
-                map.put(dependents.get(depIdx), dependents.get(depIdx));
-                // Now recurse into each bundle to get its importers.
-                populateDependentGraph(
-                    (BundleImpl) dependents.get(depIdx), map);
+                // Avoid cycles if the bundle is already in set.
+                if (!set.contains(b))
+                {
+                    // Add each dependent bundle to set.
+                    set.add(b);
+                    // Now recurse into each bundle to get its dependents.
+                    populateDependentGraph((BundleImpl) b, set);
+                }
             }
         }
     }
@@ -3879,6 +3828,8 @@
         {
             // See if we need to fire UNRESOLVED event.
             boolean fire = (bundle.getState() != Bundle.INSTALLED);
+            // Remove dependencies.
+            m_dependencies.removeDependencies(bundle);
             // Reset the bundle object.
             ((BundleImpl) bundle).refresh();
             // Fire UNRESOLVED event if necessary
@@ -4256,8 +4207,19 @@
                             // Dynamically add new wire to importing revision.
                             if (dynamicWire != null)
                             {
+                                m_dependencies.addDependent(
+                                    dynamicWire.getProvider(),
+                                    dynamicWire.getCapability(),
+                                    revision);
+
                                 ((BundleWiringImpl) revision.getWiring())
-                                    .addDynamicWire(dynamicWire);
+                                    .addDynamicWire(
+                                        new BundleWireImpl(
+                                            dynamicWire.getRequirer(),
+                                            dynamicWire.getRequirement(),
+                                            dynamicWire.getProvider(),
+                                            dynamicWire.getCapability()));
+
                                 m_logger.log(
                                     Logger.LOG_DEBUG,
                                     "DYNAMIC WIRE: " + dynamicWire);
@@ -4369,50 +4331,109 @@
                     }
                 }
 
-                // Second pass: Loop through the wire map to set wires and attach
-                // fragments, if any.
+                // Second pass: Loop through the wire map to do three things:
+                // 1) convert resolver wires to bundle wires 2) create wiring
+                // objects for revisions and 3) record dependencies among
+                // revisions. We don't actually set the wirings here because
+                // that indicates that a revision is resolved and we don't want
+                // to mark anything as resolved unless we succussfully create
+                // all wirings.
+                Map<BundleRevision, BundleWiringImpl> wirings =
+                    new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
                 for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
                 {
                     BundleRevision revision = entry.getKey();
                     List<ResolverWire> resolverWires = entry.getValue();
 
-                    Map<ResolverWire, Set<String>> requiredPkgWires =
-                        new HashMap<ResolverWire, Set<String>>();
+                    List<BundleWire> bundleWires =
+                        new ArrayList<BundleWire>(resolverWires.size());
+
+                    // Loop through resolver wires to calculate the package
+                    // space implied by the wires as well as to record the
+                    // dependencies.
+                    Map<String, BundleRevision> importedPkgs =
+                        new HashMap<String, BundleRevision>();
+                    Map<String, List<BundleRevision>> requiredPkgs =
+                        new HashMap<String, List<BundleRevision>>();
                     for (ResolverWire rw : resolverWires)
                     {
-                        if (rw.getCapability().getNamespace()
-                            .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+                        bundleWires.add(
+                            new BundleWireImpl(
+                                rw.getRequirer(),
+                                rw.getRequirement(),
+                                rw.getProvider(),
+                                rw.getCapability()));
+
+                        m_dependencies.addDependent(
+                            rw.getProvider(), rw.getCapability(), rw.getRequirer());
+
+                        if (Util.isFragment(revision))
                         {
-                            Set<String> pkgs =
-                                calculateExportedAndReexportedPackages(
-                                    rw.getProvider(),
-                                    wireMap,
-                                    new HashSet<String>(),
-                                    new HashSet<BundleRevision>());
-                            requiredPkgWires.put(rw, pkgs);
+                            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))
+                            {
+                                Set<String> pkgs = calculateExportedAndReexportedPackages(
+                                        rw.getProvider(),
+                                        wireMap,
+                                        new HashSet<String>(),
+                                        new HashSet<BundleRevision>());
+                                for (String pkg : pkgs)
+                                {
+                                    List<BundleRevision> revs = requiredPkgs.get(pkg);
+                                    if (revs == null)
+                                    {
+                                        revs = new ArrayList<BundleRevision>();
+                                        requiredPkgs.put(pkg, revs);
+                                    }
+                                    revs.add(rw.getProvider());
+                                }
+                            }
                         }
                     }
 
                     List<BundleRevision> fragments = hosts.get(revision);
                     try
                     {
-// 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);
+                        wirings.put(
+                            revision,
+                            new BundleWiringImpl(
+                                m_logger,
+                                m_configMap,
+                                this,
+                                (BundleRevisionImpl) revision,
+                                fragments,
+                                bundleWires,
+                                importedPkgs,
+                                requiredPkgs));
                     }
                     catch (Exception ex)
                     {
                         // This is a fatal error, so undo everything and
                         // throw an exception.
-                        for (Entry<BundleRevision, List<ResolverWire>> reentry : wireMap.entrySet())
+                        for (Entry<BundleRevision, BundleWiringImpl> wiringEntry
+                            : wirings.entrySet())
                         {
-                            revision = reentry.getKey();
-
-                            // Undo wires.
+                            // Dispose of wiring.
                             try
                             {
-                                ((BundleRevisionImpl) revision).resolve(null, null, null);
+                                wiringEntry.getValue().dispose();
                             }
                             catch (Exception ex2)
                             {
@@ -4438,24 +4459,28 @@
                             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
                 // and update the resolver state.
-                for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
+                for (Entry<BundleRevision, BundleWiringImpl> entry : wirings.entrySet())
                 {
-                    BundleRevision revision = entry.getKey();
+                    BundleRevisionImpl revision = (BundleRevisionImpl) entry.getKey();
+
                     // Mark revision as resolved.
-// TODO: OSGi R4.3 - See message above when we call BundleRevisionImpl.resolve().
-//                    ((BundleRevisionImpl) revision).setResolved();
+                    revision.resolve(entry.getValue());
+                    
                     // Update resolver state to remove substituted capabilities.
                     if (!Util.isFragment(revision))
                     {
+                        // Update resolver state by reindexing host with attached
+                        // fragments and removing any substituted exports.
+// TODO: OSGi R4.3 - We could avoid reindexing for fragments if we check it
+//       the revision has fragments or not.
+                        m_resolverState.addRevision(revision);
                         m_resolverState.removeSubstitutedCapabilities(revision);
                     }
+
                     // Update the state of the revision's bundle to resolved as well.
                     markBundleResolved(revision);
                 }
@@ -4551,15 +4576,20 @@
             // visibility, since we need to include those packages too.
             if (br.getWiring() == null)
             {
+System.out.println("+++ br.getWiring() = " + br.getWiring());
                 for (ResolverWire rw : wireMap.get(br))
                 {
+System.out.println("+++ rw.getCapability() = " + rw.getCapability());
+System.out.println("+++ rw.getRequirement() = " + rw.getRequirement());
                     if (rw.getCapability().getNamespace().equals(
                         BundleCapabilityImpl.BUNDLE_NAMESPACE))
                     {
                         String dir = rw.getRequirement()
                             .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+System.out.println("+++ dir = " + dir);
                         if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
                         {
+System.out.println("+++ rw.getProvider() = " + rw.getProvider());
                             calculateExportedAndReexportedPackages(
                                 rw.getProvider(),
                                 wireMap,
@@ -4782,6 +4812,8 @@
                 // current state.
                 if (m_bundle.getState() == Bundle.UNINSTALLED)
                 {
+                    // Remove dependencies.
+                    m_dependencies.removeDependencies(m_bundle);
                     m_bundle.closeAndDelete();
                     m_bundle = null;
                 }
diff --git a/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java b/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
index 0518172..1cea004 100644
--- a/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
@@ -51,34 +51,13 @@
 
     public Bundle[] getRequiringBundles()
     {
-        // Spec says to return null for stale bundles.
+        // If the package is stale, then return null per the spec.
         if (m_bundle.isStale())
         {
             return null;
         }
-
-        // We need to find all revisions that require any of the revisions
-        // associated with this bundle and save the associated bundle
-        // of the dependent revisions.
-        Set bundleSet = new HashSet();
-        // Loop through all of this bundle's revisions.
-        List<BundleRevision> revisions = m_bundle.getRevisions();
-        for (int modIdx = 0; (revisions != null) && (modIdx < revisions.size()); modIdx++)
-        {
-            // For each of this bundle's revisions, loop through all of the
-            // revisions that require it and add them to the dependents list.
-            List<BundleRevision> dependents =
-                ((BundleRevisionImpl) revisions.get(modIdx)).getDependentRequirers();
-            for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
-            {
-                if (dependents.get(depIdx).getBundle() != null)
-                {
-                    bundleSet.add(dependents.get(depIdx).getBundle());
-                }
-            }
-        }
-        // Convert to an array.
-        return (Bundle[]) bundleSet.toArray(new Bundle[bundleSet.size()]);
+        Set<Bundle> set = m_felix.getRequiringBundles(m_bundle);
+        return set.toArray(new Bundle[set.size()]);
     }
 
     public Version getVersion()
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 bdb4ade..3272b82 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -23,6 +23,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.StringTokenizer;
@@ -56,6 +57,16 @@
     // Parsed framework environments
     private final Set<String> m_fwkExecEnvSet;
 
+//    void dump()
+//    {
+//        for (Entry<String, CapabilitySet> entry : m_capSets.entrySet())
+//        {
+//            System.out.println("+++ START CAPSET " + entry.getKey());
+//            entry.getValue().dump();
+//            System.out.println("+++ END CAPSET " + entry.getKey());
+//        }
+//    }
+
     ResolverStateImpl(Logger logger, String fwkExecEnvStr)
     {
         m_logger = logger;
@@ -135,7 +146,7 @@
     }
 
 // TODO: OSGi R4.3 - This will need to be changed once BundleWiring.getCapabilities()
-//       is correctly implemented, since they already has to remove substituted caps.
+//       is correctly implemented, since it already has to remove substituted caps.
     synchronized void removeSubstitutedCapabilities(BundleRevision br)
     {
         if (br.getWiring() != null)
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 6092980..1be90ea 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -123,6 +123,7 @@
         {
             m_classPathIdx = 0;
         }
+// TODO: OSGi R4.3 - This is messed up. We need to fix resource lookup.
         if (!((BundleRevisionImpl) m_targetRevision)
             .hasInputStream(m_classPathIdx, url.getPath()))
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
index 1dfe525..7d2bd16 100644
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -41,6 +41,35 @@
     private final Set<BundleCapability> m_capSet = new HashSet<BundleCapability>();
     private final static SecureAction m_secureAction = new SecureAction();
 
+public void dump()
+{
+    for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+    {
+        boolean header1 = false;
+        for (Entry<Object, Set<BundleCapability>> entry2 : entry.getValue().entrySet())
+        {
+            boolean header2 = false;
+            for (BundleCapability cap : entry2.getValue())
+            {
+                if (cap.getRevision().getBundle().getBundleId() != 0)
+                {
+                    if (!header1)
+                    {
+                        System.out.println(entry.getKey() + ":");
+                        header1 = true;
+                    }
+                    if (!header2)
+                    {
+                        System.out.println("   " + entry2.getKey());
+                        header2 = true;
+                    }
+                    System.out.println("      " + cap);
+                }
+            }
+        }
+    }
+}
+
     public CapabilitySet(List<String> indexProps, boolean caseSensitive)
     {
         m_indices = (caseSensitive)
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 3110261..2721387 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
@@ -28,7 +28,6 @@
 import java.util.Map.Entry;
 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;