Removed PackageSource class from resolver to avoid unnecessary object allocations
and simplify data structure management. (FELIX-1781)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@827780 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 dd97fdb..644e01c 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -108,7 +108,7 @@
 
     private final Logger m_logger;
     private final Map m_headerMap = new StringMap(false);
-    private final IModule m_module;
+    private final IModule m_systemBundleModule;
     private ICapability[] m_capabilities = null;
     private Set m_exportNames = null;
     private Object m_securityContext = null;
@@ -121,7 +121,7 @@
     private ExtensionManager()
     {
         m_logger = null;
-        m_module = null;
+        m_systemBundleModule = null;
         m_extensions = new ArrayList();
         m_names = new HashSet();
         m_sourceToExtensions = new HashMap();
@@ -140,7 +140,7 @@
      */
     ExtensionManager(Logger logger, Felix felix)
     {
-        m_module = new ExtensionManagerModule(felix);
+        m_systemBundleModule = new ExtensionManagerModule(felix);
         m_extensions = null;
         m_names = null;
         m_sourceToExtensions = null;
@@ -175,7 +175,8 @@
         m_headerMap.put(FelixConstants.EXPORT_PACKAGE, syspkgs);
         try
         {
-            ManifestParser mp = new ManifestParser(m_logger, felix.getConfig(), m_headerMap);
+            ManifestParser mp = new ManifestParser(
+                m_logger, felix.getConfig(), m_systemBundleModule, m_headerMap);
             ICapability[] caps = aliasSymbolicName(mp.getCapabilities());
             setCapabilities(caps);
         }
@@ -218,6 +219,7 @@
                         new String[] { (String) attrs[i].getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME }, false);
                     // Create the aliased capability to replace the old capability.
                     aliasCaps[capIdx] = new Capability(
+                        caps[capIdx].getModule(),
                         caps[capIdx].getNamespace(),
                         ((Capability) caps[capIdx]).getDirectives(),
                         aliasAttrs);
@@ -232,7 +234,7 @@
 
     public IModule getModule()
     {
-        return m_module;
+        return m_systemBundleModule;
     }
 
     public synchronized Object getSecurityContext()
@@ -294,9 +296,10 @@
             ICapability[] exports = null;
             try
             {
-                exports = ManifestParser.parseExportHeader((String)
-                    bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE),
-                    m_module.getSymbolicName(), m_module.getVersion());
+                exports = ManifestParser.parseExportHeader(
+                    m_systemBundleModule,
+                    (String) bundle.getCurrentModule().getHeaders().get(Constants.EXPORT_PACKAGE),
+                    m_systemBundleModule.getSymbolicName(), m_systemBundleModule.getVersion());
                 exports = aliasSymbolicName(exports);
             }
             catch (Exception ex)
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 04fe2d9..9f224d2 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2953,7 +2953,7 @@
     ExportedPackage[] getExportedPackages(String pkgName)
     {
         // First, get all exporters of the package.
-        PackageSource[] exporters =
+        ICapability[] exporters =
             m_resolverState.getResolvedCandidates(
                 new Requirement(
                     ICapability.PACKAGE_NAMESPACE,
@@ -2971,7 +2971,7 @@
             for (int pkgIdx = 0; pkgIdx < exporters.length; pkgIdx++)
             {
                 // Get the bundle associated with the current exporting module.
-                BundleImpl bundle = (BundleImpl) exporters[pkgIdx].m_module.getBundle();
+                BundleImpl bundle = (BundleImpl) exporters[pkgIdx].getModule().getBundle();
 
                 // We need to find the version of the exported package, but this
                 // is tricky since there may be multiple versions of the package
@@ -3085,7 +3085,7 @@
                     // "in use" exporters of the package.
                     if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
                     {
-                        PackageSource[] inUseModules = m_resolverState.getResolvedCandidates(
+                        ICapability[] inUseCaps = m_resolverState.getResolvedCandidates(
                             new Requirement(
                                 ICapability.PACKAGE_NAMESPACE,
                                 null,
@@ -3093,9 +3093,9 @@
 
                         // Search through the current providers to find the target
                         // module.
-                        for (int i = 0; (inUseModules != null) && (i < inUseModules.length); i++)
+                        for (int i = 0; (inUseCaps != null) && (i < inUseCaps.length); i++)
                         {
-                            if (inUseModules[i].m_module == modules[modIdx])
+                            if (inUseCaps[i].getModule() == modules[modIdx])
                             {
                                 list.add(new ExportedPackageImpl(
                                     this, bundle, modules[modIdx], (Capability) caps[capIdx]));
@@ -3972,12 +3972,12 @@
             return candidateWire;
         }
 
-        public synchronized PackageSource[] getResolvedCandidates(IRequirement req)
+        public synchronized ICapability[] getResolvedCandidates(IRequirement req)
         {
             return m_resolverState.getResolvedCandidates(req);
         }
 
-        public synchronized PackageSource[] getUnresolvedCandidates(IRequirement req)
+        public synchronized ICapability[] getUnresolvedCandidates(IRequirement req)
         {
             return m_resolverState.getUnresolvedCandidates(req);
         }
diff --git a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java b/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
index 213cdc4..74acda0 100644
--- a/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
+++ b/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
@@ -25,7 +25,6 @@
 import java.util.List;
 import java.util.Map;
 import org.apache.felix.framework.searchpolicy.Resolver;
-import org.apache.felix.framework.searchpolicy.PackageSource;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.R4Attribute;
 import org.apache.felix.framework.util.manifestparser.R4Directive;
@@ -45,16 +44,16 @@
     private final List m_moduleList = new ArrayList();
     // Map of fragment symbolic names to array of modules sorted version.
     private final Map m_fragmentMap = new HashMap();
-    // Maps a package name to an array of modules.
-    private final Map m_unresolvedPkgIndexMap = new HashMap();
-    // Maps a package name to an array of modules.
-    private final Map m_resolvedPkgIndexMap = new HashMap();
+    // Maps a package name to an array of exporting capabilities.
+    private final Map m_unresolvedPkgIndex = new HashMap();
+    // Maps a package name to an array of exporting capabilities.
+    private final Map m_resolvedPkgIndex = new HashMap();
     // Maps a module to an array of capabilities.
     private final Map m_resolvedCapMap = new HashMap();
 
     // Reusable empty array.
     private static final IModule[] m_emptyModules = new IModule[0];
-    private static final PackageSource[] m_emptySources = new PackageSource[0];
+    private static final ICapability[] m_emptyCandidates = new ICapability[0];
 
     public FelixResolverState(Logger logger)
     {
@@ -158,7 +157,7 @@
                             if (fragCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
                             {
                                 indexPackageCapability(
-                                    m_unresolvedPkgIndexMap, host, fragCaps[capIdx]);
+                                    m_unresolvedPkgIndex, host, fragCaps[capIdx]);
                             }
                         }
                     }
@@ -387,7 +386,7 @@
             {
                 if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
                 {
-                    indexPackageCapability(m_unresolvedPkgIndexMap, module, caps[i]);
+                    indexPackageCapability(m_unresolvedPkgIndex, module, caps[i]);
                 }
             }
         }
@@ -435,19 +434,19 @@
                     String pkgName = (String)
                         caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
                     // Remove from "unresolved" package map.
-                    IModule[] modules = (IModule[]) m_unresolvedPkgIndexMap.get(pkgName);
+                    IModule[] modules = (IModule[]) m_unresolvedPkgIndex.get(pkgName);
                     if (modules != null)
                     {
                         modules = removeModuleFromArray(modules, module);
-                        m_unresolvedPkgIndexMap.put(pkgName, modules);
+                        m_unresolvedPkgIndex.put(pkgName, modules);
                     }
 
                     // Remove from "resolved" package map.
-                    modules = (IModule[]) m_resolvedPkgIndexMap.get(pkgName);
+                    modules = (IModule[]) m_resolvedPkgIndex.get(pkgName);
                     if (modules != null)
                     {
                         modules = removeModuleFromArray(modules, module);
-                        m_resolvedPkgIndexMap.put(pkgName, modules);
+                        m_resolvedPkgIndex.put(pkgName, modules);
                     }
                 }
             }
@@ -493,10 +492,7 @@
             if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
             {
                 // Add to "resolved" package index.
-                indexPackageCapability(
-                    m_resolvedPkgIndexMap,
-                    module,
-                    caps[i]);
+                indexPackageCapability(m_resolvedPkgIndex, module, caps[i]);
             }
         }
     }
@@ -569,10 +565,10 @@
                     String pkgName = (String)
                         caps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
                     // Remove the module's capability for the package.
-                    m_unresolvedPkgIndexMap.put(
+                    m_unresolvedPkgIndex.put(
                         pkgName,
                         removeModuleFromArray(
-                            (IModule[]) m_unresolvedPkgIndexMap.get(pkgName),
+                            (IModule[]) m_unresolvedPkgIndex.get(pkgName),
                             module));
                 }
             }
@@ -626,10 +622,7 @@
                     if (capsCopy[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
                     {
                         // Add to "resolved" package index.
-                        indexPackageCapability(
-                            m_resolvedPkgIndexMap,
-                            module,
-                            capsCopy[capIdx]);
+                        indexPackageCapability(m_resolvedPkgIndex, module, capsCopy[capIdx]);
                     }
                 }
             }
@@ -641,16 +634,16 @@
 //dumpPackageIndexMap(m_resolvedPkgIndexMap);
     }
 
-    public synchronized PackageSource[] getResolvedCandidates(IRequirement req)
+    public synchronized ICapability[] getResolvedCandidates(IRequirement req)
     {
         // Synchronized on the module manager to make sure that no
         // modules are added, removed, or resolved.
-        PackageSource[] candidates = m_emptySources;
+        ICapability[] candidates = m_emptyCandidates;
         if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
             && (((Requirement) req).getTargetName() != null))
         {
             String pkgName = ((Requirement) req).getTargetName();
-            IModule[] modules = (IModule[]) m_resolvedPkgIndexMap.get(pkgName);
+            IModule[] modules = (IModule[]) m_resolvedPkgIndex.get(pkgName);
 
             for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
             {
@@ -670,10 +663,9 @@
                     }
                     else
                     {
-                        PackageSource[] tmp = new PackageSource[candidates.length + 1];
+                        ICapability[] tmp = new ICapability[candidates.length + 1];
                         System.arraycopy(candidates, 0, tmp, 0, candidates.length);
-                        tmp[candidates.length] =
-                            new PackageSource(modules[modIdx], resolvedCap);
+                        tmp[candidates.length] = resolvedCap;
                         candidates = tmp;
                     }
                 }
@@ -706,9 +698,9 @@
                         }
                         else
                         {
-                            PackageSource[] tmp = new PackageSource[candidates.length + 1];
+                            ICapability[] tmp = new ICapability[candidates.length + 1];
                             System.arraycopy(candidates, 0, tmp, 0, candidates.length);
-                            tmp[candidates.length] = new PackageSource(module, resolvedCaps[capIdx]);
+                            tmp[candidates.length] = resolvedCaps[capIdx];
                             candidates = tmp;
                         }
                     }
@@ -719,14 +711,14 @@
         return candidates;
     }
 
-    public synchronized PackageSource[] getUnresolvedCandidates(IRequirement req)
+    public synchronized ICapability[] getUnresolvedCandidates(IRequirement req)
     {
         // Get all modules.
         IModule[] modules = null;
         if (req.getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
             (((Requirement) req).getTargetName() != null))
         {
-            modules = (IModule[]) m_unresolvedPkgIndexMap.get(((Requirement) req).getTargetName());
+            modules = (IModule[]) m_unresolvedPkgIndex.get(((Requirement) req).getTargetName());
         }
         else
         {
@@ -734,7 +726,7 @@
         }
 
         // Create list of compatible providers.
-        PackageSource[] candidates = m_emptySources;
+        ICapability[] candidates = m_emptyCandidates;
         for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
         {
             // Get the module's export package for the target package.
@@ -743,9 +735,9 @@
             // the unresolved candidate to the list.
             if ((cap != null) && !modules[modIdx].isResolved())
             {
-                PackageSource[] tmp = new PackageSource[candidates.length + 1];
+                ICapability[] tmp = new ICapability[candidates.length + 1];
                 System.arraycopy(candidates, 0, tmp, 0, candidates.length);
-                tmp[candidates.length] = new PackageSource(modules[modIdx], cap);
+                tmp[candidates.length] = cap;
                 candidates = tmp;
             }
         }
@@ -795,8 +787,8 @@
                     else if (cmp == 0)
                     {
                         // Sort further by ascending bundle ID.
-                        long middleId = Util.getBundleIdFromModuleId(modules[middle].getId());
-                        long exportId = Util.getBundleIdFromModuleId(module.getId());
+                        long middleId = modules[middle].getBundle().getBundleId();
+                        long exportId = module.getBundle().getBundleId();
                         if (middleId < exportId)
                         {
                             top = middle + 1;
@@ -857,8 +849,8 @@
                 else if (cmp == 0)
                 {
                     // Sort further by ascending bundle ID.
-                    long middleId = Util.getBundleIdFromModuleId(modules[middle].getId());
-                    long exportId = Util.getBundleIdFromModuleId(module.getId());
+                    long middleId = modules[middle].getBundle().getBundleId();
+                    long exportId = module.getBundle().getBundleId();
                     if (middleId < exportId)
                     {
                         top = middle + 1;
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 95c41c8..6c912bd 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -47,6 +47,7 @@
 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.Capability;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.apache.felix.framework.util.manifestparser.R4Library;
 import org.apache.felix.framework.util.manifestparser.Requirement;
@@ -200,7 +201,7 @@
                 (String) m_configMap.get(
                     FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP)).booleanValue();
 
-        ManifestParser mp = new ManifestParser(m_logger, m_configMap, m_headerMap);
+        ManifestParser mp = new ManifestParser(m_logger, m_configMap, this, m_headerMap);
 
         // Record some of the parsed metadata. Note, if this is an extension
         // bundle it's exports are removed, since they will be added to the
@@ -268,7 +269,12 @@
                 {
                     if (caps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
                     {
-                        capList.add(caps[capIdx]);
+                        capList.add(
+                            new Capability(
+                                this,
+                                caps[capIdx].getNamespace(),
+                                ((Capability) caps[capIdx]).getDirectives(),
+                                ((Capability) caps[capIdx]).getAttributes()));
                     }
                 }
             }
@@ -1992,7 +1998,7 @@
         String pkgName = Util.getClassPackage(name);
 
         // First, get the bundle ID of the module doing the class loader.
-        long impId = Util.getBundleIdFromModuleId(module.getId());
+        long impId = module.getBundle().getBundleId();
 
         // Next, check to see if the module imports the package.
         IWire[] wires = module.getWires();
@@ -2001,7 +2007,7 @@
             if (wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
                 wires[i].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
             {
-                long expId = Util.getBundleIdFromModuleId(wires[i].getExporter().getId());
+                long expId = wires[i].getExporter().getBundle().getBundleId();
 
                 StringBuffer sb = new StringBuffer("*** Package '");
                 sb.append(pkgName);
@@ -2160,7 +2166,7 @@
         {
             // This should never happen.
         }
-        PackageSource[] exporters =
+        ICapability[] exporters =
             resolver.getResolvedCandidates(pkgReq);
         exporters = (exporters.length == 0)
             ? resolver.getUnresolvedCandidates(pkgReq)
@@ -2182,7 +2188,7 @@
                 // Ignore
             }
 
-            long expId = Util.getBundleIdFromModuleId(exporters[0].m_module.getId());
+            long expId = exporters[0].getModule().getBundle().getBundleId();
 
             StringBuffer sb = new StringBuffer("*** Class '");
             sb.append(name);
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/PackageSource.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/PackageSource.java
deleted file mode 100644
index e2367db..0000000
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/PackageSource.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework.searchpolicy;
-
-import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.Capability;
-import org.apache.felix.moduleloader.ICapability;
-import org.apache.felix.moduleloader.IModule;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-/**
- * This utility class represents a source for a given package, where
- * the package is indicated by a particular module and the module's
- * capability associated with that package. This class also implements
- * <tt>Comparable</tt> so that two package sources can be compared based
- * on version and bundle identifiers.
- */
-public class PackageSource implements Comparable
-{
-    public IModule m_module = null;
-    public ICapability m_capability = null;
-
-    public PackageSource(IModule module, ICapability capability)
-    {
-        super();
-        m_module = module;
-        m_capability = capability;
-    }
-
-    public int compareTo(Object o)
-    {
-        PackageSource ps = (PackageSource) o;
-        Version thisVersion = null;
-        Version version = null;
-        if (m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-        {
-            thisVersion = ((Capability) m_capability).getPackageVersion();
-            version = ((Capability) ps.m_capability).getPackageVersion();
-        }
-        else if (m_capability.getNamespace().equals(ICapability.MODULE_NAMESPACE))
-        {
-            thisVersion = (Version) m_capability.getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
-            version = (Version) ps.m_capability.getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
-        }
-        if ((thisVersion != null) && (version != null))
-        {
-            int cmp = thisVersion.compareTo(version);
-            if (cmp < 0)
-            {
-                return 1;
-            }
-            else if (cmp > 0)
-            {
-                return -1;
-            }
-            else
-            {
-                long thisId = Util.getBundleIdFromModuleId(m_module.getId());
-                long id = Util.getBundleIdFromModuleId(ps.m_module.getId());
-                if (thisId < id)
-                {
-                    return -1;
-                }
-                else if (thisId > id)
-                {
-                    return 1;
-                }
-                return 0;
-            }
-        }
-        else
-        {
-            return -1;
-        }
-    }
-
-    public int hashCode()
-    {
-        final int PRIME = 31;
-        int result = 1;
-        result = PRIME * result + ((m_capability == null) ? 0 : m_capability.hashCode());
-        result = PRIME * result + ((m_module == null) ? 0 : m_module.hashCode());
-        return result;
-    }
-
-    public boolean equals(Object o)
-    {
-        if (this == o)
-        {
-            return true;
-        }
-        if (o == null)
-        {
-            return false;
-        }
-        if (getClass() != o.getClass())
-        {
-            return false;
-        }
-        PackageSource ps = (PackageSource) o;
-        return m_module.equals(ps.m_module) && (m_capability == ps.m_capability);
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
index 136f98f..28671c6 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
@@ -21,11 +21,7 @@
 import java.net.URL;
 import java.util.*;
 
-import org.apache.felix.framework.searchpolicy.PackageSource;
-import org.apache.felix.framework.searchpolicy.ResolvedPackage;
-import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.Capability;
 import org.apache.felix.moduleloader.*;
 
 public class R4WireModule implements IWire
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java
index 17d5033..b75ebfa 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ResolvedPackage.java
@@ -20,19 +20,20 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.felix.moduleloader.ICapability;
 
 /**
  * This utility class is a resolved package, which is comprised of a
- * set of <tt>PackageSource</tt>s that is calculated by the resolver
- * algorithm. A given resolved package may have a single package source,
+ * set of <tt>ICapability</tt>s that is calculated by the resolver
+ * algorithm. A given resolved package may have a single capability,
  * as is the case with imported packages, or it may have multiple
- * package sources, as is the case with required bundles.
+ * capabilities, as is the case with required bundles.
  */
 class ResolvedPackage
 {
     public final String m_name;
     public final CandidateSet m_cs;
-    public final List m_sourceList = new ArrayList();
+    public final List m_capList = new ArrayList();
 
     public ResolvedPackage(String name, CandidateSet cs)
     {
@@ -43,7 +44,7 @@
 
     public boolean isSubset(ResolvedPackage rp)
     {
-        if (m_sourceList.size() > rp.m_sourceList.size())
+        if (m_capList.size() > rp.m_capList.size())
         {
             return false;
         }
@@ -52,13 +53,13 @@
             return false;
         }
         // Determine if the target set of source modules is a subset.
-        return rp.m_sourceList.containsAll(m_sourceList);
+        return rp.m_capList.containsAll(m_capList);
     }
 
     public Object clone()
     {
         ResolvedPackage rp = new ResolvedPackage(m_name, m_cs);
-        rp.m_sourceList.addAll(m_sourceList);
+        rp.m_capList.addAll(m_capList);
         return rp;
     }
 
@@ -66,11 +67,11 @@
     {
         // Merge required packages, avoiding duplicate
         // package sources and maintaining ordering.
-        for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+        for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
         {
-            if (!m_sourceList.contains(rp.m_sourceList.get(srcIdx)))
+            if (!m_capList.contains(rp.m_capList.get(capIdx)))
             {
-                m_sourceList.add(rp.m_sourceList.get(srcIdx));
+                m_capList.add(rp.m_capList.get(capIdx));
             }
         }
     }
@@ -85,11 +86,11 @@
         sb.append(padding);
         sb.append(m_name);
         sb.append(" from [");
-        for (int i = 0; i < m_sourceList.size(); i++)
+        for (int i = 0; i < m_capList.size(); i++)
         {
-            PackageSource ps = (PackageSource) m_sourceList.get(i);
-            sb.append(ps.m_module);
-            if ((i + 1) < m_sourceList.size())
+            ICapability cap = (ICapability) m_capList.get(i);
+            sb.append(cap.getModule());
+            if ((i + 1) < m_capList.size())
             {
                 sb.append(", ");
             }
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
index e75ccef..c713ed6 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/Resolver.java
@@ -53,7 +53,6 @@
     // Reusable empty array.
     private static final IWire[] m_emptyWires = new IWire[0];
     private static final IModule[] m_emptyModules = new IModule[0];
-    private static final PackageSource[] m_emptySources = new PackageSource[0];
 
     public Resolver(Logger logger, String fwkExecEnvStr)
     {
@@ -120,7 +119,7 @@
     public Object[] resolveDynamicImport(ResolverState state, IModule importer, String pkgName)
         throws ResolveException
     {
-        PackageSource candidate = null;
+        ICapability candidate = null;
         Map resolvedModuleWireMap = null;
 
         // We can only search dynamic imports if the bundle
@@ -144,10 +143,10 @@
                     {
                         // Get "resolved" and "unresolved" candidates and put
                         // the "resolved" candidates first.
-                        PackageSource[] resolved = state.getResolvedCandidates(target);
-                        PackageSource[] unresolved = state.getUnresolvedCandidates(target);
-                        PackageSource[] candidates =
-                            new PackageSource[resolved.length + unresolved.length];
+                        ICapability[] resolved = state.getResolvedCandidates(target);
+                        ICapability[] unresolved = state.getUnresolvedCandidates(target);
+                        ICapability[] candidates =
+                            new ICapability[resolved.length + unresolved.length];
                         System.arraycopy(resolved, 0, candidates, 0, resolved.length);
                         System.arraycopy(
                             unresolved, 0, candidates, resolved.length, unresolved.length);
@@ -163,7 +162,7 @@
                                 // consistently with the importer.
                                 resolvedModuleWireMap =
                                     resolveDynamicImportCandidate(
-                                        state, candidates[candIdx].m_module, importer);
+                                        state, candidates[candIdx].getModule(), importer);
                                 if (resolvedModuleWireMap != null)
                                 {
                                     candidate = candidates[candIdx];
@@ -180,8 +179,8 @@
                             // Create the wire and add it to the module.
                             Object[] result = new Object[2];
                             result[0] = new R4Wire(
-                                importer, dynamics[dynIdx], candidate.m_module,
-                                candidate.m_capability);
+                                importer, dynamics[dynIdx], candidate.getModule(),
+                                candidate);
                             result[1] = resolvedModuleWireMap;
                             return result;
                         }
@@ -314,8 +313,8 @@
                 rp = (ResolvedPackage) rp.clone();
 
                 // Loop through all implied "uses" constraints for the current
-                // "used" package and verify that all package sources are
-                // compatible with the package source of the importing module's
+                // "used" package and verify that all packages are
+                // compatible with the packages of the importing module's
                 // package map.
                 List constraintList = (List) entry.getValue();
                 for (int constIdx = 0; constIdx < constraintList.size(); constIdx++)
@@ -324,7 +323,7 @@
                     // package.
                     ResolvedPackage rpUses = (ResolvedPackage) constraintList.get(constIdx);
                     // Determine if the implied "uses" constraint is compatible with
-                    // the improting module's package sources for the given "used"
+                    // the improting module's packages for the given "used"
                     // package. They are compatible if one is the subset of the other.
                     // Retain the union of the two sets if they are compatible.
                     if (rpUses.isSubset(rp))
@@ -334,8 +333,8 @@
                     else if (rp.isSubset(rpUses))
                     {
                         // Keep the superset, i.e., the union.
-                        rp.m_sourceList.clear();
-                        rp.m_sourceList.addAll(rpUses.m_sourceList);
+                        rp.m_capList.clear();
+                        rp.m_capList.addAll(rpUses.m_capList);
                     }
                     else
                     {
@@ -387,9 +386,9 @@
             // package maps. The "resolved" candidates have higher priority
             // than "unresolved" ones, so put the "resolved" candidates
             // at the front of the list of candidates.
-            PackageSource[] resolved = state.getResolvedCandidates(reqs[reqIdx]);
-            PackageSource[] unresolved = state.getUnresolvedCandidates(reqs[reqIdx]);
-            PackageSource[] cand = new PackageSource[resolved.length + unresolved.length];
+            ICapability[] resolved = state.getResolvedCandidates(reqs[reqIdx]);
+            ICapability[] unresolved = state.getUnresolvedCandidates(reqs[reqIdx]);
+            ICapability[] cand = new ICapability[resolved.length + unresolved.length];
             System.arraycopy(resolved, 0, cand, 0, resolved.length);
             System.arraycopy(unresolved, 0, cand, resolved.length, unresolved.length);
             List candidates = new ArrayList(Arrays.asList(cand));
@@ -405,11 +404,11 @@
                     {
                         // Only populate the resolver map with modules that
                         // are not already resolved.
-                        if (!((PackageSource) candidates.get(candIdx)).m_module.isResolved())
+                        if (!((ICapability) candidates.get(candIdx)).getModule().isResolved())
                         {
                             populateCandidatesMap(
                                 state, candidatesMap,
-                                ((PackageSource) candidates.get(candIdx)).m_module);
+                                ((ICapability) candidates.get(candIdx)).getModule());
                         }
                     }
                     catch (ResolveException ex)
@@ -423,10 +422,6 @@
                         rethrow = ex;
                     }
                 }
-
-                // Remove any nulled candidates to create the final list
-                // of available candidates.
-//                candidates = shrinkCandidateArray(candidates);
             }
 
             // If no candidates exist at this point, then throw a
@@ -497,8 +492,8 @@
                     {
                         // If the invalid module is a candidate, then remove it from
                         // the candidate set.
-                        PackageSource ps = (PackageSource) itCandidates.next();
-                        if (ps.m_module.equals(invalidModule))
+                        ICapability candCap = (ICapability) itCandidates.next();
+                        if (candCap.getModule().equals(invalidModule))
                         {
                             itCandidates.remove();
 
@@ -723,24 +718,24 @@
         }
 
         // Loop through all of the target module's accessible packages and
-        // verify that all package sources are consistent.
+        // verify that all packages are consistent.
         for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
         {
             Map.Entry entry = (Map.Entry) iter.next();
             // Get the resolved package, which contains the set of all
-            // package sources for the given package.
+            // packages for the given package.
             ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            // Loop through each package source and test if it is consistent.
-            for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+            // Loop through each capability and test if it is consistent.
+            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
             {
-                // If the module for this package source is not resolved, then
+                // If the module for this capability is not resolved, then
                 // we have to see if resolving it would violate a singleton
                 // constraint.
-                PackageSource ps = (PackageSource) rp.m_sourceList.get(srcIdx);
-                if (!ps.m_module.isResolved())
+                ICapability cap = (ICapability) rp.m_capList.get(capIdx);
+                if (!cap.getModule().isResolved())
                 {
                     return areCandidatesSingletonConsistent(
-                        state, ps.m_module, singletonMap, moduleMap, cycleMap, candidatesMap);
+                        state, cap.getModule(), singletonMap, moduleMap, cycleMap, candidatesMap);
                 }
             }
         }
@@ -791,7 +786,7 @@
 
         // Get the package map for the target module, which is a
         // map of all packages accessible to the module and their
-        // associated package sources.
+        // associated capabilities.
         Map pkgMap = null;
         try
         {
@@ -807,18 +802,18 @@
         }
 
         // Loop through all of the target module's accessible packages and
-        // verify that all package sources are consistent.
+        // verify that all packages are consistent.
         for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
         {
             Map.Entry entry = (Map.Entry) iter.next();
             // Get the resolved package, which contains the set of all
-            // package sources for the given package.
+            // capabilities for the given package.
             ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            // Loop through each package source and test if it is consistent.
-            for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+            // Loop through each capability and test if it is consistent.
+            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
             {
-                PackageSource ps = (PackageSource) rp.m_sourceList.get(srcIdx);
-                if (!isClassSpaceConsistent(ps.m_module, moduleMap, cycleMap, candidatesMap))
+                ICapability cap = (ICapability) rp.m_capList.get(capIdx);
+                if (!isClassSpaceConsistent(cap.getModule(), moduleMap, cycleMap, candidatesMap))
                 {
                     return false;
                 }
@@ -860,8 +855,8 @@
                 rp = (ResolvedPackage) rp.clone();
 
                 // Loop through all implied "uses" constraints for the current
-                // "used" package and verify that all package sources are
-                // compatible with the package source of the root module's
+                // "used" package and verify that all packages are
+                // compatible with the packages of the root module's
                 // package map.
                 List constraintList = (List) entry.getValue();
                 for (int constIdx = 0; constIdx < constraintList.size(); constIdx++)
@@ -870,7 +865,7 @@
                     // package.
                     ResolvedPackage rpUses = (ResolvedPackage) constraintList.get(constIdx);
                     // Determine if the implied "uses" constraint is compatible with
-                    // the target module's package sources for the given "used"
+                    // the target module's packages for the given "used"
                     // package. They are compatible if one is the subset of the other.
                     // Retain the union of the two sets if they are compatible.
                     if (rpUses.isSubset(rp))
@@ -880,8 +875,8 @@
                     else if (rp.isSubset(rpUses))
                     {
                         // Keep the superset, i.e., the union.
-                        rp.m_sourceList.clear();
-                        rp.m_sourceList.addAll(rpUses.m_sourceList);
+                        rp.m_capList.clear();
+                        rp.m_capList.addAll(rpUses.m_capList);
                     }
                     else
                     {
@@ -903,7 +898,7 @@
                             && (rp.m_cs.m_rotated < rp.m_cs.m_candidates.size()))
                         {
                             // Rotate candidates.
-                            PackageSource first = (PackageSource) rp.m_cs.m_candidates.get(0);
+                            ICapability first = (ICapability) rp.m_cs.m_candidates.get(0);
                             for (int i = 1; i < rp.m_cs.m_candidates.size(); i++)
                             {
                                 rp.m_cs.m_candidates.set(i - 1, rp.m_cs.m_candidates.get(i));
@@ -941,18 +936,18 @@
         Map pkgMap = getModulePackages(moduleMap, targetModule, candidatesMap);
 
         // Each package accessible from the target module is potentially
-        // comprised of one or more modules, called package sources. The
-        // "uses" constraints implied by all package sources must be
-        // calculated and combined to determine the complete set of implied
-        // "uses" constraints for each package accessible by the target module.
+        // comprised of one or more capabilities. The "uses" constraints
+        // implied by all capabilities must be calculated and combined to
+        // determine the complete set of implied "uses" constraints for
+        // each package accessible by the target module.
         for (Iterator iter = pkgMap.entrySet().iterator(); iter.hasNext(); )
         {
             Map.Entry entry = (Map.Entry) iter.next();
             ResolvedPackage rp = (ResolvedPackage) entry.getValue();
-            for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+            for (int capIdx = 0; capIdx < rp.m_capList.size(); capIdx++)
             {
                 usesMap = calculateUsesConstraints(
-                    (PackageSource) rp.m_sourceList.get(srcIdx),
+                    (ICapability) rp.m_capList.get(capIdx),
                     moduleMap, usesMap, cycleMap, candidatesMap);
             }
         }
@@ -960,31 +955,31 @@
     }
 
     private static Map calculateUsesConstraints(
-        PackageSource psTarget, Map moduleMap, Map usesMap,
+        ICapability capTarget, Map moduleMap, Map usesMap,
         Map cycleMap, Map candidatesMap)
         throws ResolveException
     {
 //System.out.println("calculateUsesConstraints2("+psTarget.m_module+")");
         // If we are in a cycle, then return for now.
-        if (cycleMap.get(psTarget) != null)
+        if (cycleMap.get(capTarget) != null)
         {
             return usesMap;
         }
 
-        // Record the target package source in the cycle map.
-        cycleMap.put(psTarget, psTarget);
+        // Record the target capability in the cycle map.
+        cycleMap.put(capTarget, capTarget);
 
         // Get all packages accessible from the module of the
-        // target package source.
-        Map pkgMap = getModulePackages(moduleMap, psTarget.m_module, candidatesMap);
+        // target capability.
+        Map pkgMap = getModulePackages(moduleMap, capTarget.getModule(), candidatesMap);
 
-        // Get capability (i.e., package) of the target package source.
-        Capability cap = (Capability) psTarget.m_capability;
+        // Cast to implementation class to get access to cached data.
+        Capability cap = (Capability) capTarget;
 
         // Loop through all "used" packages of the capability.
         for (int i = 0; i < cap.getUses().length; i++)
         {
-            // The target package source module should have a resolved package
+            // The target capability's module should have a resolved package
             // for the "used" package in its set of accessible packages,
             // since it claims to use it, so get the associated resolved
             // package.
@@ -994,13 +989,13 @@
             // but check for safety.
             if (rp != null)
             {
-                // First, iterate through all package sources for the resolved
+                // First, iterate through all capabilities for the resolved
                 // package associated with the current "used" package and calculate
-                // and combine the "uses" constraints for each package source.
-                for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+                // and combine the "uses" constraints for each package.
+                for (int srcIdx = 0; srcIdx < rp.m_capList.size(); srcIdx++)
                 {
                     usesMap = calculateUsesConstraints(
-                        (PackageSource) rp.m_sourceList.get(srcIdx),
+                        (ICapability) rp.m_capList.get(srcIdx),
                         moduleMap, usesMap, cycleMap, candidatesMap);
                 }
 
@@ -1036,7 +1031,7 @@
     /**
      * <p>
      * Calculates the module's set of accessible packages and their
-     * assocaited package sources. This method uses the current candidates
+     * assocaited package capabilities. This method uses the current candidates
      * for resolving the module's requirements from the candidate map
      * to calculate the module's accessible packages.
      * </p>
@@ -1056,8 +1051,8 @@
         Map requiredPackages = calculateRequiredPackages(module, candidatesMap);
 
         // Merge exported packages into required packages. If a package is both
-        // exported and required, then append the exported source to the end of
-        // the require package sources; otherwise just add it to the package map.
+        // exported and required, then append the exported package to the end of
+        // the require packages; otherwise just add it to the package map.
         for (Iterator i = exportedPackages.entrySet().iterator(); i.hasNext(); )
         {
             Map.Entry entry = (Map.Entry) i.next();
@@ -1065,7 +1060,7 @@
             if (rpReq != null)
             {
                 // Merge exported and required packages, avoiding duplicate
-                // package sources and maintaining ordering.
+                // packages and maintaining ordering.
                 ResolvedPackage rpExport = (ResolvedPackage) entry.getValue();
                 rpReq.merge(rpExport);
             }
@@ -1105,22 +1100,22 @@
         List candSetList = (List) candidatesMap.get(targetModule);
 
         // Loop through all candidate sets that represent import dependencies
-        // for the target module and add the current candidate's package source
+        // for the target module and add the current candidate's packages
         // to the imported package map.
         for (int candSetIdx = 0;
             (candSetList != null) && (candSetIdx < candSetList.size());
             candSetIdx++)
         {
             CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            PackageSource ps = (PackageSource) cs.m_candidates.get(cs.m_idx);
+            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
 
-            if (ps.m_capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            if (candCap.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
             {
                 String pkgName = (String)
-                    ps.m_capability.getProperties().get(ICapability.PACKAGE_PROPERTY);
+                    candCap.getProperties().get(ICapability.PACKAGE_PROPERTY);
 
                 ResolvedPackage rp = new ResolvedPackage(pkgName, cs);
-                rp.m_sourceList.add(ps);
+                rp.m_capList.add(candCap);
                 pkgMap.put(rp.m_name, rp);
             }
         }
@@ -1135,7 +1130,7 @@
         Map pkgMap = new HashMap();
 
         // Loop through the target module's wires for package
-        // dependencies and add the resolved package source to the
+        // dependencies and add the resolved packages to the
         // imported package map.
         IWire[] wires = targetModule.getWires();
         for (int wireIdx = 0; (wires != null) && (wireIdx < wires.length); wireIdx++)
@@ -1146,8 +1141,7 @@
                     wires[wireIdx].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY);
                 ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
                 rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_sourceList.add(new PackageSource(wires[wireIdx].getExporter(),
-                    wires[wireIdx].getCapability()));
+                rp.m_capList.add(wires[wireIdx].getCapability());
                 pkgMap.put(rp.m_name, rp);
             }
         }
@@ -1171,7 +1165,7 @@
                     caps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
                 ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
                 rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_sourceList.add(new PackageSource(targetModule, caps[capIdx]));
+                rp.m_capList.add(caps[capIdx]);
                 pkgMap.put(rp.m_name, rp);
             }
         }
@@ -1199,17 +1193,17 @@
             candSetIdx++)
         {
             CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            PackageSource ps = (PackageSource) cs.m_candidates.get(cs.m_idx);
+            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
 
             // If the capabaility is a module dependency, then flatten it to packages.
-            if (ps.m_capability.getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            if (candCap.getNamespace().equals(ICapability.MODULE_NAMESPACE))
             {
                 // Calculate transitively required packages.
                 Map cycleMap = new HashMap();
                 cycleMap.put(targetModule, targetModule);
                 Map requireMap =
                     calculateExportedAndReexportedPackages(
-                        ps, candidatesMap, cycleMap);
+                        candCap, candidatesMap, cycleMap);
 
                 // Take the flattened required package map for the current
                 // module dependency and merge it into the existing map
@@ -1221,7 +1215,7 @@
                     if (rp != null)
                     {
                         // Merge required packages, avoiding duplicate
-                        // package sources and maintaining ordering.
+                        // packages and maintaining ordering.
                         ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
                         rp.merge(rpReq);
                     }
@@ -1269,7 +1263,7 @@
                     if (rp != null)
                     {
                         // Merge required packages, avoiding duplicate
-                        // package sources and maintaining ordering.
+                        // packages and maintaining ordering.
                         ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
                         rp.merge(rpReq);
                     }
@@ -1285,41 +1279,41 @@
     }
 
     private static Map calculateExportedAndReexportedPackages(
-        PackageSource psTarget, Map candidatesMap, Map cycleMap)
+        ICapability capTarget, Map candidatesMap, Map cycleMap)
     {
-        return (candidatesMap.get(psTarget.m_module) == null)
-            ? calculateExportedAndReexportedPackagesResolved(psTarget.m_module, cycleMap)
-            : calculateExportedAndReexportedPackagesUnresolved(psTarget, candidatesMap, cycleMap);
+        return (candidatesMap.get(capTarget.getModule()) == null)
+            ? calculateExportedAndReexportedPackagesResolved(capTarget.getModule(), cycleMap)
+            : calculateExportedAndReexportedPackagesUnresolved(capTarget, candidatesMap, cycleMap);
     }
 
     private static Map calculateExportedAndReexportedPackagesUnresolved(
-        PackageSource psTarget, Map candidatesMap, Map cycleMap)
+        ICapability capTarget, Map candidatesMap, Map cycleMap)
     {
 //System.out.println("calculateExportedAndReexportedPackagesUnresolved("+psTarget.m_module+")");
         Map pkgMap = new HashMap();
 
-        if (cycleMap.get(psTarget.m_module) != null)
+        if (cycleMap.get(capTarget.getModule()) != null)
         {
             return pkgMap;
         }
 
-        cycleMap.put(psTarget.m_module, psTarget.m_module);
+        cycleMap.put(capTarget.getModule(), capTarget.getModule());
 
         // Loop through all current candidates for target module's dependencies
         // and calculate the module's complete set of required packages (and
-        // their associated package sources) and the complete set of required
+        // their associated packages) and the complete set of required
         // packages to be re-exported.
         Map allRequiredMap = new HashMap();
         Map reexportedPkgMap = new HashMap();
-        List candSetList = (List) candidatesMap.get(psTarget.m_module);
+        List candSetList = (List) candidatesMap.get(capTarget.getModule());
         for (int candSetIdx = 0; candSetIdx < candSetList.size(); candSetIdx++)
         {
             CandidateSet cs = (CandidateSet) candSetList.get(candSetIdx);
-            PackageSource ps = (PackageSource) cs.m_candidates.get(cs.m_idx);
+            ICapability candCap = (ICapability) cs.m_candidates.get(cs.m_idx);
 
             // If the candidate is resolving a module dependency, then
             // flatten the required packages if they are re-exported.
-            if (ps.m_capability.getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            if (candCap.getNamespace().equals(ICapability.MODULE_NAMESPACE))
             {
                 // Determine if required packages are re-exported.
                 boolean reexport = false;
@@ -1336,7 +1330,8 @@
 
                 // Recursively calculate the required packages for the
                 // current candidate.
-                Map requiredMap = calculateExportedAndReexportedPackages(ps, candidatesMap, cycleMap);
+                Map requiredMap =
+                    calculateExportedAndReexportedPackages(candCap, candidatesMap, cycleMap);
 
                 // Merge the candidate's exported and required packages
                 // into the complete set of required packages.
@@ -1350,8 +1345,8 @@
                     // We calculate all the required packages, because
                     // despite the fact that some packages will be required
                     // "privately" and some will be required "reexport", any
-                    // re-exported package sources will ultimately need to
-                    // be combined with privately required package sources,
+                    // re-exported packages will ultimately need to
+                    // be combined with privately required packages,
                     // if the required packages overlap. This is one of the
                     // bad things about require-bundle behavior, it does not
                     // necessarily obey the visibility rules declared in the
@@ -1359,7 +1354,7 @@
                     ResolvedPackage rp = (ResolvedPackage) allRequiredMap.get(pkgName);
                     if (rp != null)
                     {
-                        // Create the union of all package sources.
+                        // Create the union of all packages.
                         ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
                         rp.merge(rpReq);
                     }
@@ -1382,7 +1377,7 @@
         }
 
         // For the target module we have now calculated its entire set
-        // of required packages and their associated package sources in
+        // of required packages and their associated packages in
         // allRequiredMap and have calculated all packages to be re-exported
         // in reexportedPkgMap. Add all re-exported required packages to the
         // target module's package map since they will be part of its export
@@ -1393,9 +1388,9 @@
             pkgMap.put(pkgName, allRequiredMap.get(pkgName));
         }
 
-        // Now loop through the target module's export package capabilities and
-        // add the target module as a package source for any exported packages.
-        ICapability[] candCaps = psTarget.m_module.getCapabilities();
+        // Now loop through the target module's export package capabilities and add
+        // the target module's export capability as a source for any exported packages.
+        ICapability[] candCaps = capTarget.getModule().getCapabilities();
         for (int capIdx = 0; (candCaps != null) && (capIdx < candCaps.length); capIdx++)
         {
             if (candCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
@@ -1404,7 +1399,7 @@
                     candCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY);
                 ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
                 rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_sourceList.add(new PackageSource(psTarget.m_module, candCaps[capIdx]));
+                rp.m_capList.add(candCaps[capIdx]);
                 pkgMap.put(rp.m_name, rp);
             }
         }
@@ -1427,7 +1422,7 @@
 
         // Loop through all wires for the target module's module dependencies
         // and calculate the module's complete set of required packages (and
-        // their associated package sources) and the complete set of required
+        // their associated sources) and the complete set of required
         // packages to be re-exported.
         Map allRequiredMap = new HashMap();
         Map reexportedPkgMap = new HashMap();
@@ -1467,8 +1462,8 @@
                     // We calculate all the required packages, because
                     // despite the fact that some packages will be required
                     // "privately" and some will be required "reexport", any
-                    // re-exported package sources will ultimately need to
-                    // be combined with privately required package sources,
+                    // re-exported packages will ultimately need to
+                    // be combined with privately required packages,
                     // if the required packages overlap. This is one of the
                     // bad things about require-bundle behavior, it does not
                     // necessarily obey the visibility rules declared in the
@@ -1476,7 +1471,7 @@
                     ResolvedPackage rp = (ResolvedPackage) allRequiredMap.get(pkgName);
                     if (rp != null)
                     {
-                        // Create the union of all package sources.
+                        // Create the union of all packages.
                         ResolvedPackage rpReq = (ResolvedPackage) entry.getValue();
                         rp.merge(rpReq);
                     }
@@ -1499,7 +1494,7 @@
         }
 
         // For the target module we have now calculated its entire set
-        // of required packages and their associated package sources in
+        // of required packages and their associated source capabilities in
         // allRequiredMap and have calculated all packages to be re-exported
         // in reexportedPkgMap. Add all re-exported required packages to the
         // target module's package map since they will be part of its export
@@ -1511,7 +1506,7 @@
         }
 
         // Now loop through the target module's export package capabilities and
-        // add the target module as a package source for any exported packages.
+        // add the target module as a source for any exported packages.
         ICapability[] caps = targetModule.getCapabilities();
         for (int i = 0; (caps != null) && (i < caps.length); i++)
         {
@@ -1521,7 +1516,7 @@
                     caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
                 ResolvedPackage rp = (ResolvedPackage) pkgMap.get(pkgName);
                 rp = (rp == null) ? new ResolvedPackage(pkgName, null) : rp;
-                rp.m_sourceList.add(new PackageSource(targetModule, caps[i]));
+                rp.m_capList.add(caps[i]);
                 pkgMap.put(rp.m_name, rp);
             }
         }
@@ -1530,12 +1525,12 @@
     }
 
     private static Map calculateCandidateRequiredPackages(
-        IModule module, PackageSource psTarget, Map candidatesMap)
+        IModule module, ICapability capTarget, Map candidatesMap)
     {
 //System.out.println("calculateCandidateRequiredPackages("+module+")");
         Map cycleMap = new HashMap();
         cycleMap.put(module, module);
-        return calculateExportedAndReexportedPackages(psTarget, candidatesMap, cycleMap);
+        return calculateExportedAndReexportedPackages(capTarget, candidatesMap, cycleMap);
     }
 
     private static void incrementCandidateConfiguration(List resolverList)
@@ -1600,28 +1595,30 @@
                 moduleWires.add(new R4WireModule(
                     importer,
                     cs.m_requirement,
-                    ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_module,
-                    ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_capability,
+                    ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
+                    ((ICapability) cs.m_candidates.get(cs.m_idx)),
                     calculateCandidateRequiredPackages(
-                        importer, (PackageSource) cs.m_candidates.get(cs.m_idx), candidatesMap)));
+                        importer, (ICapability) cs.m_candidates.get(cs.m_idx), candidatesMap)));
             }
             // Create a package wire for package dependencies.
             // Filter out the case where a module imports from
             // itself, since the module should simply load from
             // its internal class path in this case.
-            else if (importer != ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_module)
+            else if (importer != ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule())
             {
                 // Add wire for imported package.
                 packageWires.add(new R4Wire(
                     importer,
                     cs.m_requirement,
-                    ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_module,
-                    ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_capability));
+                    ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
+                    ((ICapability) cs.m_candidates.get(cs.m_idx))));
             }
 
             // Create any necessary wires for the selected candidate module.
             wireMap = populateWireMap(
-                state, candidatesMap, ((PackageSource) cs.m_candidates.get(cs.m_idx)).m_module, wireMap);
+                state, candidatesMap,
+                ((ICapability) cs.m_candidates.get(cs.m_idx)).getModule(),
+                wireMap);
         }
 
         packageWires.addAll(moduleWires);
@@ -1764,34 +1761,6 @@
         return newModules;
     }
 
-    private static PackageSource[] shrinkCandidateArray(PackageSource[] candidates)
-    {
-        if (candidates == null)
-        {
-            return m_emptySources;
-        }
-
-        // Move all non-null values to one end of the array.
-        int lower = 0;
-        for (int i = 0; i < candidates.length; i++)
-        {
-            if (candidates[i] != null)
-            {
-                candidates[lower++] = candidates[i];
-            }
-        }
-
-        if (lower == 0)
-        {
-            return m_emptySources;
-        }
-
-        // Copy non-null values into a new array and return.
-        PackageSource[] newCandidates= new PackageSource[lower];
-        System.arraycopy(candidates, 0, newCandidates, 0, lower);
-        return newCandidates;
-    }
-
     //
     // Inner classes.
     //
@@ -1799,7 +1768,7 @@
     public static interface ResolverState
     {
         IModule[] getModules();
-        PackageSource[] getResolvedCandidates(IRequirement req);
-        PackageSource[] getUnresolvedCandidates(IRequirement req);
+        ICapability[] getResolvedCandidates(IRequirement req);
+        ICapability[] getUnresolvedCandidates(IRequirement req);
     }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java
index 91451b0..c87d3bc 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java
@@ -22,41 +22,46 @@
 
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.moduleloader.ICapability;
+import org.apache.felix.moduleloader.IModule;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
-public class Capability implements ICapability
+public class Capability implements ICapability, Comparable
 {
-    private String m_namespace;
-    private R4Directive[] m_directives;
-    private R4Attribute[] m_attributes;
-    private Map m_attrMap;
-    private String[] m_uses = new String[0];
-    private String[][] m_includeFilter;
-    private String[][] m_excludeFilter;
+    private final IModule m_module;
+    private final String m_namespace;
+    private final R4Directive[] m_directives;
+    private final R4Attribute[] m_attributes;
+    private final String[] m_uses;
+    private final String[][] m_includeFilter;
+    private final String[][] m_excludeFilter;
+    private volatile Map m_attrMap;
 
     // Cached properties for performance reasons.
-    private String m_pkgName;
-    private Version m_pkgVersion = Version.emptyVersion;
+    private final String m_pkgName;
+    private final Version m_pkgVersion;
 
-    public Capability(String namespace, R4Directive[] dirs, R4Attribute[] attrs)
+    public Capability(IModule module, String namespace, R4Directive[] dirs, R4Attribute[] attrs)
     {
+        m_module = module;
         m_namespace = namespace;
         m_directives = dirs;
         m_attributes = attrs;
 
         // Find all export directives: uses, mandatory, include, and exclude.
         String mandatory = "";
+        String[] uses = new String[0];
+        String[][] includeFilter = null, excludeFilter = null;
         for (int dirIdx = 0; (m_directives != null) && (dirIdx < m_directives.length); dirIdx++)
         {
             if (m_directives[dirIdx].getName().equals(Constants.USES_DIRECTIVE))
             {
                 // Parse these uses directive.
                 StringTokenizer tok = new StringTokenizer(m_directives[dirIdx].getValue(), ",");
-                m_uses = new String[tok.countTokens()];
-                for (int i = 0; i < m_uses.length; i++)
+                uses = new String[tok.countTokens()];
+                for (int i = 0; i < uses.length; i++)
                 {
-                    m_uses[i] = tok.nextToken().trim();
+                    uses[i] = tok.nextToken().trim();
                 }
             }
             else if (m_directives[dirIdx].getName().equals(Constants.MANDATORY_DIRECTIVE))
@@ -66,23 +71,28 @@
             else if (m_directives[dirIdx].getName().equals(Constants.INCLUDE_DIRECTIVE))
             {
                 String[] ss = ManifestParser.parseDelimitedString(m_directives[dirIdx].getValue(), ",");
-                m_includeFilter = new String[ss.length][];
+                includeFilter = new String[ss.length][];
                 for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
                 {
-                    m_includeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
+                    includeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
                 }
             }
             else if (m_directives[dirIdx].getName().equals(Constants.EXCLUDE_DIRECTIVE))
             {
                 String[] ss = ManifestParser.parseDelimitedString(m_directives[dirIdx].getValue(), ",");
-                m_excludeFilter = new String[ss.length][];
+                excludeFilter = new String[ss.length][];
                 for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
                 {
-                    m_excludeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
+                    excludeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
                 }
             }
         }
 
+        // Set final values.
+        m_uses = uses;
+        m_includeFilter = includeFilter;
+        m_excludeFilter = excludeFilter;
+
         // Parse mandatory directive and mark specified
         // attributes as mandatory.
         StringTokenizer tok = new StringTokenizer(mandatory, ", ");
@@ -112,17 +122,28 @@
         }
 
         // For performance reasons, find the package name and version properties.
+        String pkgName = null;
+        Version pkgVersion = Version.emptyVersion;
         for (int i = 0; i < m_attributes.length; i++)
         {
             if (m_attributes[i].getName().equals(ICapability.PACKAGE_PROPERTY))
             {
-                m_pkgName = (String) m_attributes[i].getValue();
+                pkgName = (String) m_attributes[i].getValue();
             }
             else if (m_attributes[i].getName().equals(ICapability.VERSION_PROPERTY))
             {
-                m_pkgVersion = (Version) m_attributes[i].getValue();
+                pkgVersion = (Version) m_attributes[i].getValue();
             }
         }
+
+        // Set final values.
+        m_pkgName = pkgName;
+        m_pkgVersion = pkgVersion;
+    }
+
+    public IModule getModule()
+    {
+        return m_module;
     }
 
     public String getNamespace()
@@ -312,7 +333,53 @@
         return m_attrMap;
     }
 
-// TODO: RB - Remove or simplify toString() for final version.
+    public int compareTo(Object o)
+    {
+        Capability cap = (Capability) o;
+        Version thisVersion = null;
+        Version version = null;
+        if (getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+        {
+            thisVersion = getPackageVersion();
+            version = cap.getPackageVersion();
+        }
+        else if (getNamespace().equals(ICapability.MODULE_NAMESPACE))
+        {
+            thisVersion = (Version) getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+            version = (Version) cap.getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+        }
+        if ((thisVersion != null) && (version != null))
+        {
+            int cmp = thisVersion.compareTo(version);
+            if (cmp < 0)
+            {
+                return 1;
+            }
+            else if (cmp > 0)
+            {
+                return -1;
+            }
+            else
+            {
+                long thisId = m_module.getBundle().getBundleId();
+                long id = cap.getModule().getBundle().getBundleId();
+                if (thisId < id)
+                {
+                    return -1;
+                }
+                else if (thisId > id)
+                {
+                    return 1;
+                }
+                return 0;
+            }
+        }
+        else
+        {
+            return -1;
+        }
+    }
+
     public String toString()
     {
         StringBuffer sb = new StringBuffer();
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index ab10164..df2eeb5 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -45,7 +45,7 @@
     private volatile R4LibraryClause[] m_libraryHeaders;
     private volatile boolean m_libraryHeadersOptional = false;
 
-    public ManifestParser(Logger logger, Map configMap, Map headerMap)
+    public ManifestParser(Logger logger, Map configMap, IModule owner, Map headerMap)
         throws BundleException
     {
         m_logger = logger;
@@ -91,7 +91,7 @@
         // Parse bundle symbolic name.
         //
 
-        ICapability moduleCap = parseBundleSymbolicName(m_headerMap);
+        ICapability moduleCap = parseBundleSymbolicName(owner, m_headerMap);
         if (moduleCap != null)
         {
             m_bundleSymbolicName = (String)
@@ -107,7 +107,7 @@
             {
                 capList.add(moduleCap);
                 capList.add(new Capability(
-                    ICapability.HOST_NAMESPACE, null,
+                    owner, ICapability.HOST_NAMESPACE, null,
                     ((Capability) moduleCap).getAttributes()));
             }
         }
@@ -139,7 +139,7 @@
 
         // Get exported packages from bundle manifest.
         ICapability[] exportCaps = parseExportHeader(
-            (String) headerMap.get(Constants.EXPORT_PACKAGE));
+            owner, (String) headerMap.get(Constants.EXPORT_PACKAGE));
 
         // Verify that "java.*" packages are not exported.
         for (int capIdx = 0; capIdx < exportCaps.length; capIdx++)
@@ -600,6 +600,7 @@
                     // Recreate the export to remove any other attributes
                     // and add version if missing.
                     m_capabilities[capIdx] = new Capability(
+                        m_capabilities[capIdx].getModule(),
                         ICapability.PACKAGE_NAMESPACE,
                         null,
                         new R4Attribute[] { pkgName, pkgVersion } );
@@ -728,6 +729,7 @@
             if (m_capabilities[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
             {
                 m_capabilities[i] = new Capability(
+                    m_capabilities[i].getModule(),
                     ICapability.PACKAGE_NAMESPACE,
                     new R4Directive[] { uses },
                     ((Capability) m_capabilities[i]).getAttributes());
@@ -809,6 +811,7 @@
                 newAttrs[attrs.length + 1] = new R4Attribute(
                     Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false);
                 caps[i] = new Capability(
+                    caps[i].getModule(),
                     ICapability.PACKAGE_NAMESPACE,
                     ((Capability) caps[i]).getDirectives(),
                     newAttrs);
@@ -830,7 +833,7 @@
         }
     }
 
-    private static ICapability parseBundleSymbolicName(Map headerMap)
+    private static ICapability parseBundleSymbolicName(IModule owner, Map headerMap)
         throws BundleException
     {
         Object[][][] clauses = parseStandardHeader(
@@ -856,7 +859,8 @@
             {
                 try
                 {
-                    bundleVersion = Version.parseVersion((String) headerMap.get(Constants.BUNDLE_VERSION));
+                    bundleVersion = Version.parseVersion(
+                        (String) headerMap.get(Constants.BUNDLE_VERSION));
                 }
                 catch (RuntimeException ex)
                 {
@@ -876,16 +880,21 @@
                 Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false);
             attrs[1] = new R4Attribute(
                 Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion, false);
-            return new Capability(ICapability.MODULE_NAMESPACE, (R4Directive[]) clauses[0][CLAUSE_DIRECTIVES_INDEX], attrs);
+            return new Capability(
+                owner,
+                ICapability.MODULE_NAMESPACE,
+                (R4Directive[]) clauses[0][CLAUSE_DIRECTIVES_INDEX],
+                attrs);
         }
 
         return null;
     }
 
-    public static ICapability[] parseExportHeader(String header, String bsn, Version bv)
+    public static ICapability[] parseExportHeader(
+        IModule owner, String header, String bsn, Version bv)
         throws BundleException
     {
-        ICapability[] caps = parseExportHeader(header);
+        ICapability[] caps = parseExportHeader(owner, header);
         try
         {
             caps = checkAndNormalizeR4Exports(caps, bsn, bv);
@@ -897,7 +906,7 @@
         return caps;
     }
 
-    private static ICapability[] parseExportHeader(String header)
+    private static ICapability[] parseExportHeader(IModule owner, String header)
     {
         Object[][][] clauses = parseStandardHeader(header);
 
@@ -984,6 +993,7 @@
                 // Create package capability and add to capability list.
                 capList.add(
                     new Capability(
+                        owner,
                         ICapability.PACKAGE_NAMESPACE,
                         (R4Directive[]) clauses[clauseIdx][CLAUSE_DIRECTIVES_INDEX],
                         newAttrs));
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/ICapability.java b/framework/src/main/java/org/apache/felix/moduleloader/ICapability.java
index 328a459..fdc8509 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/ICapability.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/ICapability.java
@@ -29,6 +29,7 @@
     public static final String PACKAGE_PROPERTY = "package";
     public static final String VERSION_PROPERTY = "version";
 
+    IModule getModule();
     String getNamespace();
     Map getProperties();
 }
\ No newline at end of file