Manage a module's resolved capabilities/requirements separately from
its resolved capabilities/requirements. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102786 13f79535-47bb-0310-9956-ffa450edef68
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 8177940..7b34e7f 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -646,7 +646,15 @@
             }
         }
 
-        public List<BundleCapabilityImpl> getCapabilities()
+        public List<BundleCapabilityImpl> getDeclaredCapabilities()
+        {
+            synchronized (ExtensionManager.this)
+            {
+                return m_capabilities;
+            }
+        }
+
+        public List<BundleCapabilityImpl> getResolvedCapabilities()
         {
             synchronized (ExtensionManager.this)
             {
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 8a07255..a7f1603 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3283,24 +3283,27 @@
                 // that the first module found to be exporting the package is the
                 // provider of the package, which makes sense since it must have
                 // been resolved first.
-                List<Module> modules = bundle.getModules();
-                for (int modIdx = 0; modIdx < modules.size(); modIdx++)
+                for (Module m : bundle.getModules())
                 {
-                    List<BundleCapabilityImpl> ec = modules.get(modIdx).getCapabilities();
-                    for (int i = 0; (ec != null) && (i < ec.size()); i++)
+                    List<BundleCapabilityImpl> caps = (m.isResolved())
+                        ? m.getResolvedCapabilities()
+                        : m.getDeclaredCapabilities();
+                    for (BundleCapabilityImpl cap : caps)
                     {
-                        if (ec.get(i).getNamespace().equals(req.getNamespace())
-                            && CapabilitySet.matches(ec.get(i), req.getFilter()))
+                        if (cap.getNamespace().equals(req.getNamespace())
+                            && CapabilitySet.matches(cap, req.getFilter()))
                         {
                             pkgs.add(
                                 new ExportedPackageImpl(
-                                    this, bundle, modules.get(modIdx), ec.get(i)));
+                                    this, bundle, m, cap));
                         }
                     }
                 }
             }
 
-            return (pkgs.isEmpty()) ? null : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
+            return (pkgs.isEmpty())
+                ? null
+                : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
         }
 
         return null;
@@ -3381,20 +3384,21 @@
         // Since a bundle may have many modules associated with it,
         // one for each revision in the cache, search each module
         // for each revision to get all exports.
-        List<Module> modules = bundle.getModules();
-        for (int modIdx = 0; modIdx < modules.size(); modIdx++)
+        for (Module m : bundle.getModules())
         {
-            List<BundleCapabilityImpl> caps = modules.get(modIdx).getCapabilities();
+            List<BundleCapabilityImpl> caps = (m.isResolved())
+                ? m.getResolvedCapabilities()
+                : m.getDeclaredCapabilities();
             if ((caps != null) && (caps.size() > 0))
             {
-                for (int capIdx = 0; capIdx < caps.size(); capIdx++)
+                for (BundleCapabilityImpl cap : caps)
                 {
                     // See if the target bundle's module is one of the
                     // resolved exporters of the package.
-                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                    if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         String pkgName = (String)
-                            caps.get(capIdx).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+                            cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
                         Map<String, Object> attrs = new HashMap<String, Object>(1);
                         attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
                         BundleRequirementImpl req =
@@ -3403,9 +3407,11 @@
                             BundleCapabilityImpl.PACKAGE_NAMESPACE,
                             Collections.EMPTY_MAP,
                             attrs);
-                        Set<BundleCapabilityImpl> exports = m_resolver.getCandidates(req, false);
+                        Set<BundleCapabilityImpl> providers =
+                            m_resolver.getCandidates(req, false);
                         // We only want resolved capabilities.
-                        for (Iterator<BundleCapabilityImpl> it = exports.iterator(); it.hasNext(); )
+                        for (Iterator<BundleCapabilityImpl> it = providers.iterator();
+                            it.hasNext(); )
                         {
                             if (!it.next().getModule().isResolved())
                             {
@@ -3413,14 +3419,12 @@
                             }
                         }
 
-
                         // Search through the current providers to find the target module.
-                        for (BundleCapabilityImpl cap : exports)
+                        for (BundleCapabilityImpl provider : providers)
                         {
-                            if (cap == caps.get(capIdx))
+                            if (provider == cap)
                             {
-                                list.add(new ExportedPackageImpl(
-                                    this, bundle, modules.get(modIdx), caps.get(capIdx)));
+                                list.add(new ExportedPackageImpl(this, bundle, m, cap));
                             }
                         }
                     }
@@ -4249,7 +4253,7 @@
 
             // If the module doesn't have dynamic imports, then just return
             // immediately.
-            List<BundleRequirementImpl> dynamics = module.getDynamicRequirements();
+            List<BundleRequirementImpl> dynamics = module.getResolvedDynamicRequirements();
             if ((dynamics == null) || dynamics.isEmpty())
             {
                 return false;
@@ -4257,21 +4261,19 @@
 
             // If any of the module exports this package, then we cannot
             // attempt to dynamically import it.
-            List<BundleCapabilityImpl> caps = module.getCapabilities();
-            for (int i = 0; (caps != null) && (i < caps.size()); i++)
+            for (BundleCapabilityImpl cap : module.getResolvedCapabilities())
             {
-                if (caps.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                    && caps.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+                if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                    && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
                 {
                     return false;
                 }
             }
             // If any of our wires have this package, then we cannot
             // attempt to dynamically import it.
-            List<Wire> wires = module.getWires();
-            for (int i = 0; (wires != null) && (i < wires.size()); i++)
+            for (Wire w : module.getWires())
             {
-                if (wires.get(i).hasPackage(pkgName))
+                if (w.hasPackage(pkgName))
                 {
                     return false;
                 }
diff --git a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index 188db9c..0c9d719 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -81,12 +81,12 @@
     private final String m_symbolicName;
     private final Version m_version;
 
-    private final List<BundleCapabilityImpl> m_capabilities;
-    private List<BundleCapabilityImpl> m_cachedCapabilities = null;
-    private final List<BundleRequirementImpl> m_requirements;
-    private List<BundleRequirementImpl> m_cachedRequirements = null;
-    private final List<BundleRequirementImpl> m_dynamicRequirements;
-    private List<BundleRequirementImpl> m_cachedDynamicRequirements = null;
+    private final List<BundleCapabilityImpl> m_declaredCaps;
+    private List<BundleCapabilityImpl> m_resolvedCaps = null;
+    private final List<BundleRequirementImpl> m_declaredReqs;
+    private List<BundleRequirementImpl> m_resolvedReqs = null;
+    private final List<BundleRequirementImpl> m_declaredDynReqs;
+    private List<BundleRequirementImpl> m_resolvedDynReqs = null;
     private final List<R4Library> m_nativeLibraries;
     private final int m_declaredActivationPolicy;
     private final List<String> m_activationIncludes;
@@ -183,9 +183,9 @@
         m_symbolicName = null;
         m_isExtension = false;
         m_version = null;
-        m_capabilities = null;
-        m_requirements = null;
-        m_dynamicRequirements = null;
+        m_declaredCaps = Collections.EMPTY_LIST;
+        m_declaredReqs = Collections.EMPTY_LIST;
+        m_declaredDynReqs = Collections.EMPTY_LIST;
         m_nativeLibraries = null;
         m_declaredActivationPolicy = EAGER_ACTIVATION;
         m_activationExcludes = null;
@@ -244,9 +244,9 @@
         // system bundle directly later on.
         m_manifestVersion = mp.getManifestVersion();
         m_version = mp.getBundleVersion();
-        m_capabilities = mp.isExtension() ? null : mp.getCapabilities();
-        m_requirements = mp.getRequirements();
-        m_dynamicRequirements = mp.getDynamicRequirements();
+        m_declaredCaps = mp.isExtension() ? null : mp.getCapabilities();
+        m_declaredReqs = mp.getRequirements();
+        m_declaredDynReqs = mp.getDynamicRequirements();
         m_nativeLibraries = mp.getLibraries();
         m_declaredActivationPolicy = mp.getActivationPolicy();
         m_activationExcludes = (mp.getActivationExcludeDirective() == null)
@@ -288,86 +288,108 @@
         return m_version;
     }
 
-    public synchronized List<BundleCapabilityImpl> getCapabilities()
+    public synchronized List<BundleCapabilityImpl> getDeclaredCapabilities()
     {
-        if (m_cachedCapabilities == null)
+        return m_declaredCaps;
+    }
+
+    public synchronized List<BundleCapabilityImpl> getResolvedCapabilities()
+    {
+        if (m_isResolved && (m_resolvedCaps == null))
         {
-            List capList = (m_capabilities == null)
+            List capList = (m_declaredCaps == null)
                 ? new ArrayList<BundleCapabilityImpl>()
-                : new ArrayList<BundleCapabilityImpl>(m_capabilities);
+                : new ArrayList<BundleCapabilityImpl>(m_declaredCaps);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<BundleCapabilityImpl> caps = m_fragments.get(fragIdx).getCapabilities();
+                List<BundleCapabilityImpl> caps =
+                    m_fragments.get(fragIdx).getDeclaredCapabilities();
                 for (int capIdx = 0;
                     (caps != null) && (capIdx < caps.size());
                     capIdx++)
                 {
-                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                    if (caps.get(capIdx).getNamespace().equals(
+                        BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         capList.add(
                             new HostedCapability(this, caps.get(capIdx)));
                     }
                 }
             }
-            m_cachedCapabilities = Collections.unmodifiableList(capList);
+            m_resolvedCaps = Collections.unmodifiableList(capList);
         }
-        return m_cachedCapabilities;
+        return m_resolvedCaps;
     }
 
-    public synchronized List<BundleRequirementImpl> getRequirements()
+    public synchronized List<BundleRequirementImpl> getDeclaredRequirements()
     {
-        if (m_cachedRequirements == null)
+        return m_declaredReqs;
+    }
+
+    public synchronized List<BundleRequirementImpl> getResolvedRequirements()
+    {
+        if (m_isResolved && (m_resolvedReqs == null))
         {
-            List<BundleRequirementImpl> reqList = (m_requirements == null)
-                ? new ArrayList() : new ArrayList(m_requirements);
+            List<BundleRequirementImpl> reqList = (m_declaredReqs == null)
+                ? new ArrayList() : new ArrayList(m_declaredReqs);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<BundleRequirementImpl> reqs = m_fragments.get(fragIdx).getRequirements();
+                List<BundleRequirementImpl> reqs =
+                    m_fragments.get(fragIdx).getDeclaredRequirements();
                 for (int reqIdx = 0;
                     (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                        || reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
+                    if (reqs.get(reqIdx).getNamespace().equals(
+                            BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                        || reqs.get(reqIdx).getNamespace().equals(
+                            BundleCapabilityImpl.MODULE_NAMESPACE))
                     {
                         reqList.add(
                             new HostedRequirement(this, reqs.get(reqIdx)));
                     }
                 }
             }
-            m_cachedRequirements = Collections.unmodifiableList(reqList);
+            m_resolvedReqs = Collections.unmodifiableList(reqList);
         }
-        return m_cachedRequirements;
+        return m_resolvedReqs;
     }
 
-    public synchronized List<BundleRequirementImpl> getDynamicRequirements()
+    public synchronized List<BundleRequirementImpl> getDeclaredDynamicRequirements()
     {
-        if (m_cachedDynamicRequirements == null)
+        return m_declaredDynReqs;
+    }
+
+    public synchronized List<BundleRequirementImpl> getResolvedDynamicRequirements()
+    {
+        if (m_isResolved && (m_resolvedDynReqs == null))
         {
-            List<BundleRequirementImpl> reqList = (m_dynamicRequirements == null)
-                ? new ArrayList() : new ArrayList(m_dynamicRequirements);
+            List<BundleRequirementImpl> reqList = (m_declaredDynReqs == null)
+                ? new ArrayList() : new ArrayList(m_declaredDynReqs);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<BundleRequirementImpl> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
+                List<BundleRequirementImpl> reqs =
+                    m_fragments.get(fragIdx).getDeclaredDynamicRequirements();
                 for (int reqIdx = 0;
                     (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                    if (reqs.get(reqIdx).getNamespace().equals(
+                        BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         reqList.add(reqs.get(reqIdx));
                     }
                 }
             }
-            m_cachedDynamicRequirements = Collections.unmodifiableList(reqList);
+            m_resolvedDynReqs = Collections.unmodifiableList(reqList);
         }
-        return m_cachedDynamicRequirements;
+        return m_resolvedDynReqs;
     }
 
     public synchronized List<R4Library> getNativeLibraries()
@@ -1216,9 +1238,9 @@
         m_contentPath = null;
 
         // Remove cached capabilities and requirements.
-        m_cachedCapabilities = null;
-        m_cachedRequirements = null;
-        m_cachedDynamicRequirements = null;
+        m_resolvedCaps = null;
+        m_resolvedReqs = null;
+        m_resolvedDynReqs = null;
 
         // Update the dependencies on the new fragments.
         m_fragments = fragments;
@@ -2238,7 +2260,7 @@
 
         // Next, check to see if the package was optionally imported and
         // whether or not there is an exporter available.
-        List<BundleRequirementImpl> reqs = module.getRequirements();
+        List<BundleRequirementImpl> reqs = module.getResolvedRequirements();
 /*
 * TODO: RB - Fix diagnostic message for optional imports.
         for (int i = 0; (reqs != null) && (i < reqs.length); i++)
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 ef71fb1..7f26dcf 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -81,7 +81,9 @@
     synchronized void addModule(Module m)
     {
         m_modules.add(m);
-        List<BundleCapabilityImpl> caps = m.getCapabilities();
+        List<BundleCapabilityImpl> caps = (m.isResolved())
+            ? m.getResolvedCapabilities()
+            : m.getDeclaredCapabilities();
         if (caps != null)
         {
             for (BundleCapabilityImpl cap : caps)
@@ -105,7 +107,9 @@
     synchronized void removeModule(Module m)
     {
         m_modules.remove(m);
-        List<BundleCapabilityImpl> caps = m.getCapabilities();
+        List<BundleCapabilityImpl> caps = (m.isResolved())
+            ? m.getResolvedCapabilities()
+            : m.getDeclaredCapabilities();
         if (caps != null)
         {
             for (BundleCapabilityImpl cap : caps)
@@ -129,31 +133,26 @@
         return new HashSet(m_fragments);
     }
 
-    synchronized void removeSubstitutedCapabilities(Module module)
+    synchronized void removeSubstitutedCapabilities(Module m)
     {
-        if (module.isResolved())
+        if (m.isResolved())
         {
             // Loop through the module's package wires and determine if any
             // of them overlap any of the packages exported by the module.
             // If so, then the framework must have chosen to have the module
             // import rather than export the package, so we need to remove the
             // corresponding package capability from the package capability set.
-            List<Wire> wires = module.getWires();
-            List<BundleCapabilityImpl> caps = module.getCapabilities();
-            for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
+            for (Wire w : m.getWires())
             {
-                Wire wire = wires.get(wireIdx);
-                if (wire.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
-                    for (int capIdx = 0;
-                        (caps != null) && (capIdx < caps.size());
-                        capIdx++)
+                    for (BundleCapabilityImpl cap : m.getResolvedCapabilities())
                     {
-                        if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                            && wire.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
-                                .equals(caps.get(capIdx).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)))
+                        if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                            && w.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
+                                .equals(cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)))
                         {
-                            m_capSets.get(BundleCapabilityImpl.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
+                            m_capSets.get(BundleCapabilityImpl.PACKAGE_NAMESPACE).removeCapability(cap);
                             break;
                         }
                     }
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 269a12d..83ff55f 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
@@ -214,7 +214,7 @@
             localCandidateMap = new HashMap();
 
             // Create a modifiable list of the module's requirements.
-            remainingReqs = new ArrayList(module.getRequirements());
+            remainingReqs = new ArrayList(module.getDeclaredRequirements());
 
             // Add these value to the result cache so we know we are
             // in the middle of populating candidates for the current
@@ -313,6 +313,16 @@
 
     public final void populateOptional(ResolverState state, Module module)
     {
+        // We will always attempt to populate optional fragments, since this
+        // is necessary for greedy resolving of fragment. Howevere, we'll only
+        // attempt to populate optional non-fragment modules if they aren't
+        // already resolved.
+        boolean isFragment = Util.isFragment(module);
+        if (!isFragment && module.isResolved())
+        {
+            return;
+        }
+
         try
         {
             // If the optional module is a fragment, then we only want to populate
@@ -320,7 +330,6 @@
             // modules. We do this to avoid unnecessary work in prepare(). If the
             // fragment has a host, we'll prepopulate the result cache here to avoid
             // having to do the host lookup again in populate().
-            boolean isFragment = Util.isFragment(module);
             if (isFragment)
             {
                 // Get the current result cache value, to make sure the module
@@ -329,11 +338,13 @@
                 if (cacheValue == null)
                 {
                     // Create a modifiable list of the module's requirements.
-                    List<BundleRequirementImpl> remainingReqs = new ArrayList(module.getRequirements());
+                    List<BundleRequirementImpl> remainingReqs =
+                        new ArrayList(module.getDeclaredRequirements());
 
                     // Find the host requirement.
                     BundleRequirementImpl hostReq = null;
-                    for (Iterator<BundleRequirementImpl> it = remainingReqs.iterator(); it.hasNext(); )
+                    for (Iterator<BundleRequirementImpl> it = remainingReqs.iterator();
+                        it.hasNext(); )
                     {
                         BundleRequirementImpl r = it.next();
                         if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
@@ -691,7 +702,7 @@
         {
             // Replaces capabilities from fragments with the capabilities
             // from the merged host.
-            for (BundleCapabilityImpl c : hostModule.getCapabilities())
+            for (BundleCapabilityImpl c : hostModule.getDeclaredCapabilities())
             {
                 Set<BundleRequirementImpl> dependents =
                     m_dependentMap.get(((HostedCapability) c).getDeclaredCapability());
@@ -709,7 +720,7 @@
             // Copies candidates for fragment requirements to the host.
             // This doesn't record the reverse dependency, but that
             // information should not be needed at this point anymore.
-            for (BundleRequirementImpl r : hostModule.getRequirements())
+            for (BundleRequirementImpl r : hostModule.getDeclaredRequirements())
             {
                 SortedSet<BundleCapabilityImpl> cands =
                     m_candidateMap.get(((HostedRequirement) r).getDeclaredRequirement());
@@ -809,12 +820,12 @@
     **/
     private void remove(Module m, Set<Module> unresolvedModules) throws ResolveException
     {
-        for (BundleRequirementImpl r : m.getRequirements())
+        for (BundleRequirementImpl r : m.getDeclaredRequirements())
         {
             remove(r);
         }
 
-        for (BundleCapabilityImpl c : m.getCapabilities())
+        for (BundleCapabilityImpl c : m.getDeclaredCapabilities())
         {
             remove(c, unresolvedModules);
         }
@@ -958,7 +969,10 @@
         {
             System.out.println("  " + module
                  + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
-            for (BundleRequirementImpl req : module.getRequirements())
+            List<BundleRequirementImpl> reqs = (module.isResolved())
+                ? module.getResolvedRequirements()
+                : module.getDeclaredRequirements();
+            for (BundleRequirementImpl req : reqs)
             {
                 Set<BundleCapabilityImpl> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
@@ -966,7 +980,10 @@
                     System.out.println("    " + req + ": " + candidates);
                 }
             }
-            for (BundleRequirementImpl req : module.getDynamicRequirements())
+            reqs = (module.isResolved())
+                ? module.getResolvedDynamicRequirements()
+                : module.getDeclaredDynamicRequirements();
+            for (BundleRequirementImpl req : reqs)
             {
                 Set<BundleCapabilityImpl> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java
index dbd8b9f..0bf4037 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostModule.java
@@ -60,83 +60,79 @@
         return m_host.getId();
     }
 
-    public List<BundleCapabilityImpl> getCapabilities()
+    public List<BundleCapabilityImpl> getDeclaredCapabilities()
     {
         if (m_cachedCapabilities == null)
         {
-            List<BundleCapabilityImpl> capList = new ArrayList<BundleCapabilityImpl>();
+            List<BundleCapabilityImpl> caps = new ArrayList<BundleCapabilityImpl>();
 
             // Wrap host capabilities.
-            List<BundleCapabilityImpl> caps = m_host.getCapabilities();
-            for (int capIdx = 0;
-                (caps != null) && (capIdx < caps.size());
-                capIdx++)
+            for (BundleCapabilityImpl cap : m_host.getDeclaredCapabilities())
             {
-                capList.add(
-                    new HostedCapability(this, caps.get(capIdx)));
+                caps.add(new HostedCapability(this, cap));
             }
 
             // Wrap fragment capabilities.
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
+            if (m_fragments != null)
             {
-                caps = m_fragments.get(fragIdx).getCapabilities();
-                for (int capIdx = 0;
-                    (caps != null) && (capIdx < caps.size());
-                    capIdx++)
+                for (Module fragment : m_fragments)
                 {
-                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                    for (BundleCapabilityImpl cap : fragment.getDeclaredCapabilities())
                     {
-                        capList.add(
-                            new HostedCapability(this, caps.get(capIdx)));
+                        if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                        {
+                            caps.add(new HostedCapability(this, cap));
+                        }
                     }
                 }
             }
-            m_cachedCapabilities = Collections.unmodifiableList(capList);
+            m_cachedCapabilities = Collections.unmodifiableList(caps);
         }
         return m_cachedCapabilities;
     }
 
-    public List<BundleRequirementImpl> getRequirements()
+    public List<BundleCapabilityImpl> getResolvedCapabilities()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<BundleRequirementImpl> getDeclaredRequirements()
     {
         if (m_cachedRequirements == null)
         {
-            List<BundleRequirementImpl> reqList = new ArrayList<BundleRequirementImpl>();
+            List<BundleRequirementImpl> reqs = new ArrayList<BundleRequirementImpl>();
 
             // Wrap host requirements.
-            List<BundleRequirementImpl> reqs = m_host.getRequirements();
-            for (int reqIdx = 0;
-                (reqs != null) && (reqIdx < reqs.size());
-                reqIdx++)
+            for (BundleRequirementImpl req : m_host.getDeclaredRequirements())
             {
-                reqList.add(
-                    new HostedRequirement(this, reqs.get(reqIdx)));
+                reqs.add(new HostedRequirement(this, req));
             }
 
             // Wrap fragment requirements.
-            for (int fragIdx = 0;
-                (m_fragments != null) && (fragIdx < m_fragments.size());
-                fragIdx++)
+            if (m_fragments != null)
             {
-                reqs = m_fragments.get(fragIdx).getRequirements();
-                for (int reqIdx = 0;
-                    (reqs != null) && (reqIdx < reqs.size());
-                    reqIdx++)
+                for (Module fragment : m_fragments)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                        || reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
+                    for (BundleRequirementImpl req : fragment.getDeclaredRequirements())
                     {
-                        reqList.add(
-                            new HostedRequirement(this, reqs.get(reqIdx)));
+                        if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                            || req.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
+                        {
+                            reqs.add(new HostedRequirement(this, req));
+                        }
                     }
                 }
             }
-            m_cachedRequirements = Collections.unmodifiableList(reqList);
+            m_cachedRequirements = Collections.unmodifiableList(reqs);
         }
         return m_cachedRequirements;
     }
 
+    public List<BundleRequirementImpl> getResolvedRequirements()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     public String toString()
     {
         return m_host.getId();
@@ -162,7 +158,12 @@
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    public List<BundleRequirementImpl> getDynamicRequirements()
+    public List<BundleRequirementImpl> getDeclaredDynamicRequirements()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<BundleRequirementImpl> getResolvedDynamicRequirements()
     {
         throw new UnsupportedOperationException("Not supported yet.");
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
index 465dac7..823d3cb 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
@@ -40,15 +40,18 @@
     boolean isExtension();
     String getSymbolicName();
     Version getVersion();
-    List<BundleCapabilityImpl> getCapabilities();
-    List<BundleRequirementImpl> getRequirements();
-    List<BundleRequirementImpl> getDynamicRequirements();
+    List<BundleCapabilityImpl> getDeclaredCapabilities();
+    List<BundleRequirementImpl> getDeclaredRequirements();
+    List<BundleRequirementImpl> getDeclaredDynamicRequirements();
     List<R4Library> getNativeLibraries();
     int getDeclaredActivationPolicy();
 
     // Run-time data access methods.
     Bundle getBundle();
     String getId();
+    List<BundleCapabilityImpl> getResolvedCapabilities();
+    List<BundleRequirementImpl> getResolvedRequirements();
+    List<BundleRequirementImpl> getResolvedDynamicRequirements();
     List<Wire> getWires();
     boolean isResolved();
     Object getSecurityContext();
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 ef0d694..a7db0f9 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
@@ -317,7 +317,7 @@
 
     private static BundleCapabilityImpl getHostCapability(Module m)
     {
-        for (BundleCapabilityImpl c : m.getCapabilities())
+        for (BundleCapabilityImpl c : m.getDeclaredCapabilities())
         {
             if (c.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
             {
@@ -329,7 +329,7 @@
 
     private static BundleRequirementImpl getHostRequirement(Module m)
     {
-        for (BundleRequirementImpl r : m.getRequirements())
+        for (BundleRequirementImpl r : m.getDeclaredRequirements())
         {
             if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
             {
@@ -351,7 +351,7 @@
 
         // If the module doesn't have dynamic imports, then just return
         // immediately.
-        List<BundleRequirementImpl> dynamics = module.getDynamicRequirements();
+        List<BundleRequirementImpl> dynamics = module.getResolvedDynamicRequirements();
         if ((dynamics == null) || dynamics.isEmpty())
         {
             return null;
@@ -359,21 +359,19 @@
 
         // If any of the module exports this package, then we cannot
         // attempt to dynamically import it.
-        List<BundleCapabilityImpl> caps = module.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.size()); i++)
+        for (BundleCapabilityImpl cap : module.getResolvedCapabilities())
         {
-            if (caps.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
-                && caps.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
+            if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                && cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
             {
                 return null;
             }
         }
         // If any of our wires have this package, then we cannot
         // attempt to dynamically import it.
-        List<Wire> wires = module.getWires();
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        for (Wire w : module.getWires())
         {
-            if (wires.get(i).hasPackage(pkgName))
+            if (w.hasPackage(pkgName))
             {
                 return null;
             }
@@ -382,11 +380,13 @@
         // Loop through the importer's dynamic requirements to determine if
         // there is a matching one for the package from which we want to
         // load a class.
-        Map<String, String> dirs = Collections.EMPTY_MAP;
         Map<String, Object> attrs = new HashMap(1);
         attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
         BundleRequirementImpl req = new BundleRequirementImpl(
-            module, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
+            module,
+            BundleCapabilityImpl.PACKAGE_NAMESPACE,
+            Collections.EMPTY_MAP,
+            attrs);
         SortedSet<BundleCapabilityImpl> candidates = state.getCandidates(req, false);
 
         // First find a dynamic requirement that matches the capabilities.
@@ -480,7 +480,7 @@
             // Since the module is resolved, it could be dynamically importing,
             // so check to see if there are candidates for any of its dynamic
             // imports.
-            for (BundleRequirementImpl req : module.getDynamicRequirements())
+            for (BundleRequirementImpl req : module.getResolvedDynamicRequirements())
             {
                 // Get the candidates for the current requirement.
                 SortedSet<BundleCapabilityImpl> candCaps = allCandidates.getCandidates(req);
@@ -501,7 +501,7 @@
         }
         else
         {
-            for (BundleRequirementImpl req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getDeclaredRequirements())
             {
                 // Get the candidates for the current requirement.
                 SortedSet<BundleCapabilityImpl> candCaps = allCandidates.getCandidates(req);
@@ -624,7 +624,10 @@
 
             // If the candidate requires any other bundles with reexport visibility,
             // then we also need to merge their packages too.
-            for (BundleRequirementImpl req : candCap.getModule().getRequirements())
+            List<BundleRequirementImpl> reqs = (candCap.getModule().isResolved())
+                ? candCap.getModule().getResolvedRequirements()
+                : candCap.getModule().getDeclaredRequirements();
+            for (BundleRequirementImpl req : reqs)
             {
                 if (req.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
                 {
@@ -1130,9 +1133,12 @@
         packages = new Packages(module);
 
         // Get all exported packages.
+        List<BundleCapabilityImpl> caps = (module.isResolved())
+            ? module.getResolvedCapabilities()
+            : module.getDeclaredCapabilities();
         Map<String, BundleCapabilityImpl> exports =
-            new HashMap<String, BundleCapabilityImpl>(module.getCapabilities().size());
-        for (BundleCapabilityImpl cap : module.getCapabilities())
+            new HashMap<String, BundleCapabilityImpl>(caps.size());
+        for (BundleCapabilityImpl cap : caps)
         {
             if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
@@ -1149,7 +1155,8 @@
         {
             for (Wire wire : module.getWires())
             {
-                if (wire.getRequirement().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+                if (wire.getRequirement().getNamespace().equals(
+                    BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     String pkgName = (String) wire.getCapability()
                         .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
@@ -1159,7 +1166,7 @@
         }
         else
         {
-            for (BundleRequirementImpl req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getDeclaredRequirements())
             {
                 if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
@@ -1248,7 +1255,9 @@
 
             // Since a module can export the same package more than once, get
             // all package capabilities for the specified package name.
-            List<BundleCapabilityImpl> caps = cap.getModule().getCapabilities();
+            List<BundleCapabilityImpl> caps = (cap.getModule().isResolved())
+                ? cap.getModule().getResolvedCapabilities()
+                : cap.getModule().getDeclaredCapabilities();
             for (int capIdx = 0; capIdx < caps.size(); capIdx++)
             {
                 if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
@@ -1313,7 +1322,7 @@
             List<Wire> packageWires = new ArrayList<Wire>();
             List<Wire> moduleWires = new ArrayList<Wire>();
 
-            for (BundleRequirementImpl req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getDeclaredRequirements())
             {
                 SortedSet<BundleCapabilityImpl> cands = allCandidates.getCandidates(req);
                 if ((cands != null) && (cands.size() > 0))
@@ -1576,7 +1585,10 @@
             // 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.
-            for (BundleCapabilityImpl cap : m_module.getCapabilities())
+            List<BundleCapabilityImpl> caps = (m_module.isResolved())
+                ? m_module.getResolvedCapabilities()
+                : m_module.getDeclaredCapabilities();
+            for (BundleCapabilityImpl cap : caps)
             {
                 if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index ab691c9..842a63b 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
@@ -281,13 +281,18 @@
 
     public static BundleCapabilityImpl getSatisfyingCapability(Module m, BundleRequirementImpl req)
     {
-        List<BundleCapabilityImpl> caps = m.getCapabilities();
-        for (int i = 0; (caps != null) && (i < caps.size()); i++)
+        List<BundleCapabilityImpl> caps = (m.isResolved())
+            ? m.getResolvedCapabilities()
+            : m.getDeclaredCapabilities();
+        if (caps != null)
         {
-            if (caps.get(i).getNamespace().equals(req.getNamespace())
-                && CapabilitySet.matches(caps.get(i), req.getFilter()))
+            for (BundleCapabilityImpl cap : caps)
             {
-                return caps.get(i);
+                if (cap.getNamespace().equals(req.getNamespace())
+                    && CapabilitySet.matches(cap, req.getFilter()))
+                {
+                    return cap;
+                }
             }
         }
         return null;
@@ -296,19 +301,24 @@
     /**
      * Returns all the capabilities from a module that has a specified namespace.
      *
-     * @param module    module providing capabilities
+     * @param m    module providing capabilities
      * @param namespace capability namespace
      * @return array of matching capabilities or empty if none found
      */
-    public static List<BundleCapabilityImpl> getCapabilityByNamespace(Module module, String namespace)
+    public static List<BundleCapabilityImpl> getCapabilityByNamespace(Module m, String namespace)
     {
         final List<BundleCapabilityImpl> matching = new ArrayList();
-        final List<BundleCapabilityImpl> caps = module.getCapabilities();
-        for (int capIdx = 0; (caps != null) && (capIdx < caps.size()); capIdx++)
+        final List<BundleCapabilityImpl> caps = (m.isResolved())
+            ? m.getResolvedCapabilities()
+            : m.getDeclaredCapabilities();
+        if (caps != null)
         {
-            if (caps.get(capIdx).getNamespace().equals(namespace))
+            for (BundleCapabilityImpl cap : caps)
             {
-                matching.add(caps.get(capIdx));
+                if (cap.getNamespace().equals(namespace))
+                {
+                    matching.add(cap);
+                }
             }
         }
         return matching;
@@ -317,12 +327,15 @@
     public static Wire getWire(Module m, String name)
     {
         List<Wire> wires = m.getWires();
-        for (int i = 0; (wires != null) && (i < wires.size()); i++)
+        if (wires != null)
         {
-            if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
-                wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+            for (Wire w : wires)
             {
-                return wires.get(i);
+                if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                    w.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+                {
+                    return w;
+                }
             }
         }
         return null;