Use BundleCapability/BundleRequirement. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102776 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/pom.xml b/framework/pom.xml
index 5cbdb1f..e2bc4b8 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -55,7 +55,7 @@
             <Bundle-Name>Apache Felix Framework</Bundle-Name>
             <Bundle-Description>OSGi R4 framework implementation.</Bundle-Description>
             <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
-            <Export-Package>org.osgi.framework;-split-package:=merge-first,org.osgi.framework.launch,org.osgi.framework.hooks.service,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
+            <Export-Package>org.osgi.framework.*;-split-package:=merge-first,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
             <Private-Package>org.apache.felix.framework.*</Private-Package>
             <Import-Package>!*</Import-Package>
             <Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES,{src/main/resources/}</Include-Resource> 
diff --git a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
index abb4fed..ede1cf2 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
@@ -19,8 +19,8 @@
 package org.apache.felix.framework;
 
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
 import org.osgi.service.packageadmin.ExportedPackage;
@@ -30,21 +30,21 @@
     private final Felix m_felix;
     private final BundleImpl m_exportingBundle;
     private final Module m_exportingModule;
-    private final Capability m_export;
+    private final BundleCapabilityImpl m_export;
     private final String m_pkgName;
     private final Version m_version;
 
     public ExportedPackageImpl(
-        Felix felix, BundleImpl exporter, Module module, Capability export)
+        Felix felix, BundleImpl exporter, Module module, BundleCapabilityImpl export)
     {
         m_felix = felix;
         m_exportingBundle = exporter;
         m_exportingModule = module;
         m_export = export;
-        m_pkgName = (String) m_export.getAttribute(Capability.PACKAGE_ATTR).getValue();
-        m_version = (m_export.getAttribute(Capability.VERSION_ATTR) == null)
+        m_pkgName = (String) m_export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+        m_version = (!m_export.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
             ? Version.emptyVersion
-            : (Version) m_export.getAttribute(Capability.VERSION_ATTR).getValue();
+            : (Version) m_export.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
     }
 
     public Bundle getExportingBundle()
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 46c83a3..8177940 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -33,20 +33,18 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Set;
 
 import org.apache.felix.framework.Felix.StatefulResolver;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.apache.felix.framework.resolver.Content;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -118,7 +116,7 @@
     private final Logger m_logger;
     private final Map m_headerMap = new StringMap(false);
     private final Module m_systemBundleModule;
-    private List<Capability> m_capabilities = null;
+    private List<BundleCapabilityImpl> m_capabilities = null;
     private Set m_exportNames = null;
     private Object m_securityContext = null;
     private final List m_extensions;
@@ -192,12 +190,12 @@
         {
             ManifestParser mp = new ManifestParser(
                 m_logger, felix.getConfig(), m_systemBundleModule, m_headerMap);
-            List<Capability> caps = aliasSymbolicName(mp.getCapabilities());
+            List<BundleCapabilityImpl> caps = aliasSymbolicName(mp.getCapabilities());
             setCapabilities(caps);
         }
         catch (Exception ex)
         {
-            m_capabilities = new ArrayList<Capability>(0);
+            m_capabilities = new ArrayList<BundleCapabilityImpl>(0);
             m_logger.log(
                 Logger.LOG_ERROR,
                 "Error parsing system bundle export statement: "
@@ -205,35 +203,35 @@
         }
     }
 
-    private static List<Capability> aliasSymbolicName(List<Capability> caps)
+    private static List<BundleCapabilityImpl> aliasSymbolicName(List<BundleCapabilityImpl> caps)
     {
         if (caps == null)
         {
-            return new ArrayList<Capability>(0);
+            return new ArrayList<BundleCapabilityImpl>(0);
         }
 
-        List<Capability> aliasCaps = new ArrayList<Capability>(caps);
+        List<BundleCapabilityImpl> aliasCaps = new ArrayList<BundleCapabilityImpl>(caps);
 
         for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
         {
             // Get the attributes and search for bundle symbolic name.
-            List<Attribute> attrs = aliasCaps.get(capIdx).getAttributes();
-            for (int i = 0; i < attrs.size(); i++)
+            for (Entry<String, Object> entry : aliasCaps.get(capIdx).getAttributes().entrySet())
             {
                 // If there is a bundle symbolic name attribute, add the
                 // standard alias as a value.
-                if (attrs.get(i).getName().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                if (entry.getKey().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
                 {
                     // Make a copy of the attribute array.
-                    List<Attribute> aliasAttrs = new ArrayList<Attribute>(attrs);
+                    Map<String, Object> aliasAttrs =
+                        new HashMap<String, Object>(aliasCaps.get(capIdx).getAttributes());
                     // Add the aliased value.
-                    aliasAttrs.set(i, new Attribute(
+                    aliasAttrs.put(
                         Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
                         new String[] {
-                            (String) attrs.get(i).getValue(), Constants.SYSTEM_BUNDLE_SYMBOLICNAME},
-                        false));
+                            (String) entry.getValue(),
+                            Constants.SYSTEM_BUNDLE_SYMBOLICNAME});
                     // Create the aliased capability to replace the old capability.
-                    aliasCaps.set(capIdx, new CapabilityImpl(
+                    aliasCaps.set(capIdx, new BundleCapabilityImpl(
                         caps.get(capIdx).getModule(),
                         caps.get(capIdx).getNamespace(),
                         caps.get(capIdx).getDirectives(),
@@ -299,21 +297,21 @@
             throw new SecurityException("Extension Bundles must have AllPermission");
         }
 
-        Directive dir = ManifestParser.parseExtensionBundleHeader((String)
+        String directive = ManifestParser.parseExtensionBundleHeader((String)
             bundle.getCurrentModule().getHeaders().get(Constants.FRAGMENT_HOST));
 
         // We only support classpath extensions (not bootclasspath).
-        if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
+        if (!Constants.EXTENSION_FRAMEWORK.equals(directive))
         {
             throw new BundleException("Unsupported Extension Bundle type: " +
-                dir.getValue(), new UnsupportedOperationException(
+                directive, new UnsupportedOperationException(
                 "Unsupported Extension Bundle type!"));
         }
 
         try
         {
             // Merge the exported packages with the exported packages of the systembundle.
-            List<Capability> exports = null;
+            List<BundleCapabilityImpl> exports = null;
             try
             {
                 exports = ManifestParser.parseExportHeader(
@@ -346,7 +344,8 @@
                 throw new UnsupportedOperationException(
                     "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
             }
-            List<Capability> temp = new ArrayList<Capability>(m_capabilities.size() + exports.size());
+            List<BundleCapabilityImpl> temp =
+                new ArrayList<BundleCapabilityImpl>(m_capabilities.size() + exports.size());
             temp.addAll(m_capabilities);
             temp.addAll(exports);
             setCapabilities(temp);
@@ -416,7 +415,7 @@
         }
     }
 
-    private void setCapabilities(List<Capability> capabilities)
+    private void setCapabilities(List<BundleCapabilityImpl> capabilities)
     {
         m_capabilities = capabilities;
         m_headerMap.put(Constants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(m_headerMap));
@@ -429,7 +428,7 @@
 
         for (int i = 0; (m_capabilities != null) && (i < m_capabilities.size()); i++)
         {
-            if (m_capabilities.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            if (m_capabilities.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 // Add a comma separate if there is an existing package.
                 if (exportSB.length() > 0)
@@ -438,31 +437,35 @@
                 }
 
                 // Append exported package information.
-                exportSB.append(m_capabilities.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
-                for (Directive dir : m_capabilities.get(i).getDirectives())
+                exportSB.append(m_capabilities.get(i)
+                    .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+                for (Entry<String, String> entry
+                    : m_capabilities.get(i).getDirectives().entrySet())
                 {
                     exportSB.append("; ");
-                    exportSB.append(dir.getName());
+                    exportSB.append(entry.getKey());
                     exportSB.append(":=\"");
-                    exportSB.append(dir.getValue());
+                    exportSB.append(entry.getValue());
                     exportSB.append("\"");
                 }
-                for (Attribute attr : m_capabilities.get(i).getAttributes())
+                for (Entry<String, Object> entry
+                    : m_capabilities.get(i).getAttributes().entrySet())
                 {
-                    if (!attr.getName().equals(Capability.PACKAGE_ATTR)
-                        && !attr.getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
-                        && !attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+                    if (!entry.getKey().equals(BundleCapabilityImpl.PACKAGE_ATTR)
+                        && !entry.getKey().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+                        && !entry.getKey().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
                     {
                         exportSB.append("; ");
-                        exportSB.append(attr.getName());
+                        exportSB.append(entry.getKey());
                         exportSB.append("=\"");
-                        exportSB.append(attr.getValue());
+                        exportSB.append(entry.getValue());
                         exportSB.append("\"");
                     }
                 }
 
                 // Remember exported packages.
-                exportNames.add(m_capabilities.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
+                exportNames.add(m_capabilities.get(i)
+                    .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
             }
         }
 
@@ -643,7 +646,7 @@
             }
         }
 
-        public List<Capability> getCapabilities()
+        public List<BundleCapabilityImpl> getCapabilities()
         {
             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 d5b8610..8a07255 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -27,12 +27,8 @@
 import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
 import org.apache.felix.framework.cache.BundleArchive;
 import org.apache.felix.framework.cache.BundleCache;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.resolver.Module;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.Wire;
 import org.apache.felix.framework.ext.SecurityProvider;
@@ -49,7 +45,8 @@
 import org.apache.felix.framework.util.ThreadGate;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
-import org.apache.felix.framework.util.manifestparser.RequirementImpl;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
@@ -3249,14 +3246,17 @@
     ExportedPackage[] getExportedPackages(String pkgName)
     {
         // First, get all exporters of the package.
-        List<Directive> dirs = new ArrayList<Directive>(0);
-        List<Attribute> attrs = new ArrayList<Attribute>(1);
-        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-        Requirement req = new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<Capability> exports = m_resolver.getCandidates(req, false);
+        Map<String, Object> attrs = new HashMap<String, Object>(1);
+        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+        BundleRequirementImpl req = new BundleRequirementImpl(
+            null,
+            BundleCapabilityImpl.PACKAGE_NAMESPACE,
+            Collections.EMPTY_MAP,
+            attrs);
+        Set<BundleCapabilityImpl> exports = m_resolver.getCandidates(req, false);
 
         // We only want resolved capabilities.
-        for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
+        for (Iterator<BundleCapabilityImpl> it = exports.iterator(); it.hasNext(); )
         {
             if (!it.next().getModule().isResolved())
             {
@@ -3268,7 +3268,7 @@
         {
             List pkgs = new ArrayList();
 
-            for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
+            for (Iterator<BundleCapabilityImpl> it = exports.iterator(); it.hasNext(); )
             {
                 // Get the bundle associated with the current exporting module.
                 BundleImpl bundle = (BundleImpl) it.next().getModule().getBundle();
@@ -3286,7 +3286,7 @@
                 List<Module> modules = bundle.getModules();
                 for (int modIdx = 0; modIdx < modules.size(); modIdx++)
                 {
-                    List<Capability> ec = modules.get(modIdx).getCapabilities();
+                    List<BundleCapabilityImpl> ec = modules.get(modIdx).getCapabilities();
                     for (int i = 0; (ec != null) && (i < ec.size()); i++)
                     {
                         if (ec.get(i).getNamespace().equals(req.getNamespace())
@@ -3384,25 +3384,28 @@
         List<Module> modules = bundle.getModules();
         for (int modIdx = 0; modIdx < modules.size(); modIdx++)
         {
-            List<Capability> caps = modules.get(modIdx).getCapabilities();
+            List<BundleCapabilityImpl> caps = modules.get(modIdx).getCapabilities();
             if ((caps != null) && (caps.size() > 0))
             {
                 for (int capIdx = 0; capIdx < caps.size(); capIdx++)
                 {
                     // See if the target bundle's module is one of the
                     // resolved exporters of the package.
-                    if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         String pkgName = (String)
-                            caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue();
-                        List<Directive> dirs = new ArrayList<Directive>(0);
-                        List<Attribute> attrs = new ArrayList<Attribute>(1);
-                        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-                        Requirement req =
-                            new RequirementImpl(null, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-                        Set<Capability> exports = m_resolver.getCandidates(req, false);
+                            caps.get(capIdx).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
+                        Map<String, Object> attrs = new HashMap<String, Object>(1);
+                        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+                        BundleRequirementImpl req =
+                            new BundleRequirementImpl(
+                            null,
+                            BundleCapabilityImpl.PACKAGE_NAMESPACE,
+                            Collections.EMPTY_MAP,
+                            attrs);
+                        Set<BundleCapabilityImpl> exports = m_resolver.getCandidates(req, false);
                         // We only want resolved capabilities.
-                        for (Iterator<Capability> it = exports.iterator(); it.hasNext(); )
+                        for (Iterator<BundleCapabilityImpl> it = exports.iterator(); it.hasNext(); )
                         {
                             if (!it.next().getModule().isResolved())
                             {
@@ -3412,7 +3415,7 @@
 
 
                         // Search through the current providers to find the target module.
-                        for (Capability cap : exports)
+                        for (BundleCapabilityImpl cap : exports)
                         {
                             if (cap == caps.get(capIdx))
                             {
@@ -4113,7 +4116,7 @@
             m_resolverState.removeModule(m);
         }
 
-        Set<Capability> getCandidates(Requirement req, boolean obeyMandatory)
+        Set<BundleCapabilityImpl> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
         {
             return m_resolverState.getCandidates(req, obeyMandatory);
         }
@@ -4246,7 +4249,7 @@
 
             // If the module doesn't have dynamic imports, then just return
             // immediately.
-            List<Requirement> dynamics = module.getDynamicRequirements();
+            List<BundleRequirementImpl> dynamics = module.getDynamicRequirements();
             if ((dynamics == null) || dynamics.isEmpty())
             {
                 return false;
@@ -4254,11 +4257,11 @@
 
             // If any of the module exports this package, then we cannot
             // attempt to dynamically import it.
-            List<Capability> caps = module.getCapabilities();
+            List<BundleCapabilityImpl> caps = module.getCapabilities();
             for (int i = 0; (caps != null) && (i < caps.size()); i++)
             {
-                if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                    && caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+                if (caps.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                    && caps.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
                 {
                     return false;
                 }
@@ -4277,12 +4280,14 @@
             // 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.
-            List<Directive> dirs = Collections.EMPTY_LIST;
-            List<Attribute> attrs = new ArrayList(1);
-            attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-            Requirement req = new RequirementImpl(
-                module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-            Set<Capability> candidates = m_resolverState.getCandidates(req, false);
+            Map<String, Object> attrs = new HashMap(1);
+            attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+            BundleRequirementImpl req = new BundleRequirementImpl(
+                module,
+                BundleCapabilityImpl.PACKAGE_NAMESPACE,
+                Collections.EMPTY_MAP,
+                attrs);
+            Set<BundleCapabilityImpl> candidates = m_resolverState.getCandidates(req, false);
 
             return !candidates.isEmpty();
         }
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
index e245b3a..5d5733d 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -18,17 +18,20 @@
  */
 package org.apache.felix.framework;
 
-import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.apache.felix.framework.ServiceRegistrationImpl.ServiceReferenceImpl;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -51,7 +54,7 @@
 
     public boolean match(ServiceReference sr)
     {
-        return CapabilitySet.matches(new ServiceReferenceCapability(sr), m_filter);
+        return CapabilitySet.matches((ServiceReferenceImpl) sr, m_filter);
     }
 
     public boolean match(Dictionary dctnr)
@@ -79,12 +82,53 @@
         return m_filter.toString();
     }
 
-    static class DictionaryCapability implements Capability
+    static class DictionaryCapability extends BundleCapabilityImpl
+    {
+        private final Map m_map;
+
+        public DictionaryCapability(Dictionary dict, boolean caseSensitive)
+        {
+            super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+            m_map = new DictionaryMap(dict, caseSensitive);
+        }
+
+        @Override
+        public Module getModule()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public String getNamespace()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public Map<String, String> getDirectives()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public Map<String, Object> getAttributes()
+        {
+            return m_map;
+        }
+
+        @Override
+        public List<String> getUses()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    private static class DictionaryMap implements Map
     {
         private final StringMap m_map;
         private final Dictionary m_dict;
 
-        public DictionaryCapability(Dictionary dict, boolean caseSensitive)
+        public DictionaryMap(Dictionary dict, boolean caseSensitive)
         {
             m_dict = dict;
             if (!caseSensitive)
@@ -114,29 +158,29 @@
             }
         }
 
-        public Module getModule()
+        public int size()
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
-        public String getNamespace()
+        public boolean isEmpty()
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
-        public Directive getDirective(String name)
+        public boolean containsKey(Object o)
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
-        public List<Directive> getDirectives()
+        public boolean containsValue(Object o)
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
-        public Attribute getAttribute(String name)
+        public Object get(Object o)
         {
-            String key = name;
+            String key = (String) o;
             Object value = null;
             if (m_dict != null)
             {
@@ -145,7 +189,7 @@
                 // the key.
                 if (m_map != null)
                 {
-                    key = (String) m_map.get(name);
+                    key = (String) m_map.get(o);
                 }
                 // If the key could not be found in the case insensitive
                 // key map, then avoid doing the dictionary lookup on it.
@@ -154,63 +198,42 @@
                     value = m_dict.get(key);
                 }
             }
-            return (value == null) ? null : new Attribute(key, value, false);
+            return value;
         }
 
-        public List<Attribute> getAttributes()
-        {
-            return new ArrayList();
-        }
-
-        public List<String> getUses()
+        public Object put(Object k, Object v)
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
+
+        public Object remove(Object o)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void putAll(Map map)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void clear()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Set<Object> keySet()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Collection<Object> values()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Set<Entry<Object, Object>> entrySet()
+        {
+            return Collections.EMPTY_SET;
+        }
     }
-
-    static class ServiceReferenceCapability implements Capability
-    {
-        private final ServiceReference m_sr;
-
-        public ServiceReferenceCapability(ServiceReference sr)
-        {
-            m_sr = sr;
-        }
-
-        public Module getModule()
-        {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
-        public String getNamespace()
-        {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
-        public Directive getDirective(String name)
-        {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
-        public List<Directive> getDirectives()
-        {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-
-        public Attribute getAttribute(String name)
-        {
-            Object value = m_sr.getProperty(name);
-            return (value == null) ? null : new Attribute(name, value, false);
-        }
-
-        public List<Attribute> getAttributes()
-        {
-            return new ArrayList();
-        }
-
-        public List<String> getUses()
-        {
-            throw new UnsupportedOperationException("Not supported yet.");
-        }
-    }
-}
+}
\ No newline at end of file
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 0ee825a..188db9c 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -44,10 +44,6 @@
 
 import org.apache.felix.framework.Felix.StatefulResolver;
 import org.apache.felix.framework.cache.JarContent;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.resolver.Content;
 import org.apache.felix.framework.resolver.HostedCapability;
 import org.apache.felix.framework.resolver.HostedRequirement;
@@ -62,7 +58,8 @@
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.apache.felix.framework.util.manifestparser.R4Library;
-import org.apache.felix.framework.util.manifestparser.RequirementImpl;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.BundleReference;
@@ -84,12 +81,12 @@
     private final String m_symbolicName;
     private final Version m_version;
 
-    private final List<Capability> m_capabilities;
-    private List<Capability> m_cachedCapabilities = null;
-    private final List<Requirement> m_requirements;
-    private List<Requirement> m_cachedRequirements = null;
-    private final List<Requirement> m_dynamicRequirements;
-    private List<Requirement> m_cachedDynamicRequirements = null;
+    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<R4Library> m_nativeLibraries;
     private final int m_declaredActivationPolicy;
     private final List<String> m_activationIncludes;
@@ -291,23 +288,23 @@
         return m_version;
     }
 
-    public synchronized List<Capability> getCapabilities()
+    public synchronized List<BundleCapabilityImpl> getCapabilities()
     {
         if (m_cachedCapabilities == null)
         {
             List capList = (m_capabilities == null)
-                ? new ArrayList<Capability>()
-                : new ArrayList<Capability>(m_capabilities);
+                ? new ArrayList<BundleCapabilityImpl>()
+                : new ArrayList<BundleCapabilityImpl>(m_capabilities);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<Capability> caps = m_fragments.get(fragIdx).getCapabilities();
+                List<BundleCapabilityImpl> caps = m_fragments.get(fragIdx).getCapabilities();
                 for (int capIdx = 0;
                     (caps != null) && (capIdx < caps.size());
                     capIdx++)
                 {
-                    if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         capList.add(
                             new HostedCapability(this, caps.get(capIdx)));
@@ -319,23 +316,23 @@
         return m_cachedCapabilities;
     }
 
-    public synchronized List<Requirement> getRequirements()
+    public synchronized List<BundleRequirementImpl> getRequirements()
     {
         if (m_cachedRequirements == null)
         {
-            List<Requirement> reqList = (m_requirements == null)
+            List<BundleRequirementImpl> reqList = (m_requirements == null)
                 ? new ArrayList() : new ArrayList(m_requirements);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<Requirement> reqs = m_fragments.get(fragIdx).getRequirements();
+                List<BundleRequirementImpl> reqs = m_fragments.get(fragIdx).getRequirements();
                 for (int reqIdx = 0;
                     (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                        || reqs.get(reqIdx).getNamespace().equals(Capability.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)));
@@ -347,22 +344,22 @@
         return m_cachedRequirements;
     }
 
-    public synchronized List<Requirement> getDynamicRequirements()
+    public synchronized List<BundleRequirementImpl> getDynamicRequirements()
     {
         if (m_cachedDynamicRequirements == null)
         {
-            List<Requirement> reqList = (m_dynamicRequirements == null)
+            List<BundleRequirementImpl> reqList = (m_dynamicRequirements == null)
                 ? new ArrayList() : new ArrayList(m_dynamicRequirements);
             for (int fragIdx = 0;
                 (m_fragments != null) && (fragIdx < m_fragments.size());
                 fragIdx++)
             {
-                List<Requirement> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
+                List<BundleRequirementImpl> reqs = m_fragments.get(fragIdx).getDynamicRequirements();
                 for (int reqIdx = 0;
                     (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    if (reqs.get(reqIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         reqList.add(reqs.get(reqIdx));
                     }
@@ -482,11 +479,11 @@
         // from the old wires.
         for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
         {
-            if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
+            if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
             {
                 ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentRequirer(this);
             }
-            else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            else if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 ((ModuleImpl) m_wires.get(i).getExporter()).removeDependentImporter(this);
             }
@@ -497,11 +494,11 @@
         // Add ourself as a dependent to the new wires' modules.
         for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
         {
-            if (m_wires.get(i).getCapability().getNamespace().equals(Capability.MODULE_NAMESPACE))
+            if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
             {
                 ((ModuleImpl) m_wires.get(i).getExporter()).addDependentRequirer(this);
             }
-            else if (m_wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            else if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 ((ModuleImpl) m_wires.get(i).getExporter()).addDependentImporter(this);
             }
@@ -936,7 +933,7 @@
         for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
             if (wires.get(i).getRequirement().getNamespace()
-                .equals(Capability.PACKAGE_NAMESPACE))
+                .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 try
                 {
@@ -962,7 +959,7 @@
         for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
             if (wires.get(i).getRequirement().getNamespace()
-                .equals(Capability.MODULE_NAMESPACE))
+                .equals(BundleCapabilityImpl.MODULE_NAMESPACE))
             {
                 try
                 {
@@ -2214,8 +2211,8 @@
         List<Wire> wires = module.getWires();
         for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
-            if (wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-                wires.get(i).getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+            if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
             {
                 String exporter = wires.get(i).getExporter().getBundle().toString();
 
@@ -2241,7 +2238,7 @@
 
         // Next, check to see if the package was optionally imported and
         // whether or not there is an exporter available.
-        List<Requirement> reqs = module.getRequirements();
+        List<BundleRequirementImpl> reqs = module.getRequirements();
 /*
 * TODO: RB - Fix diagnostic message for optional imports.
         for (int i = 0; (reqs != null) && (i < reqs.length); i++)
@@ -2304,12 +2301,12 @@
         if (resolver.isAllowedDynamicImport(module, pkgName))
         {
             // Try to see if there is an exporter available.
-            List<Directive> dirs = Collections.EMPTY_LIST;
-            List<Attribute> attrs = new ArrayList(1);
-            attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-            Requirement req = new RequirementImpl(
-                module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-            Set<Capability> exporters = resolver.getCandidates(req, false);
+            Map<String, String> dirs = Collections.EMPTY_MAP;
+            Map<String, Object> attrs = new HashMap<String, Object>(1);
+            attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+            BundleRequirementImpl req = new BundleRequirementImpl(
+                module, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
+            Set<BundleCapabilityImpl> exporters = resolver.getCandidates(req, false);
 
             Wire wire = null;
             try
@@ -2343,12 +2340,12 @@
         }
 
         // Next, check to see if there are any exporters for the package at all.
-        List<Directive> dirs = Collections.EMPTY_LIST;
-        List<Attribute> attrs = new ArrayList(1);
-        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-        Requirement req = new RequirementImpl(
-            module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<Capability> exports = resolver.getCandidates(req, false);
+        Map<String, String> dirs = Collections.EMPTY_MAP;
+        Map<String, Object> attrs = new HashMap<String, Object>(1);
+        attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
+        BundleRequirementImpl req = new BundleRequirementImpl(
+            module, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
+        Set<BundleCapabilityImpl> exports = resolver.getCandidates(req, false);
         if (exports.size() > 0)
         {
             boolean classpath = false;
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 f9937b0..ef71fb1 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -27,9 +27,7 @@
 import java.util.SortedSet;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.resolver.CandidateComparator;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.resolver.ResolveException;
@@ -37,6 +35,8 @@
 import org.apache.felix.framework.resolver.Wire;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.BundlePermission;
 import org.osgi.framework.Constants;
 import org.osgi.framework.PackagePermission;
@@ -67,24 +67,24 @@
 
         List<String> indices = new ArrayList<String>();
         indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
-        m_capSets.put(Capability.MODULE_NAMESPACE, new CapabilitySet(indices, true));
+        m_capSets.put(BundleCapabilityImpl.MODULE_NAMESPACE, new CapabilitySet(indices, true));
 
         indices = new ArrayList<String>();
-        indices.add(Capability.PACKAGE_ATTR);
-        m_capSets.put(Capability.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+        indices.add(BundleCapabilityImpl.PACKAGE_ATTR);
+        m_capSets.put(BundleCapabilityImpl.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
 
         indices = new ArrayList<String>();
         indices.add(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
-        m_capSets.put(Capability.HOST_NAMESPACE,  new CapabilitySet(indices, true));
+        m_capSets.put(BundleCapabilityImpl.HOST_NAMESPACE,  new CapabilitySet(indices, true));
     }
 
     synchronized void addModule(Module m)
     {
         m_modules.add(m);
-        List<Capability> caps = m.getCapabilities();
+        List<BundleCapabilityImpl> caps = m.getCapabilities();
         if (caps != null)
         {
-            for (Capability cap : caps)
+            for (BundleCapabilityImpl cap : caps)
             {
                 CapabilitySet capSet = m_capSets.get(cap.getNamespace());
                 if (capSet == null)
@@ -105,10 +105,10 @@
     synchronized void removeModule(Module m)
     {
         m_modules.remove(m);
-        List<Capability> caps = m.getCapabilities();
+        List<BundleCapabilityImpl> caps = m.getCapabilities();
         if (caps != null)
         {
-            for (Capability cap : caps)
+            for (BundleCapabilityImpl cap : caps)
             {
                 CapabilitySet capSet = m_capSets.get(cap.getNamespace());
                 if (capSet != null)
@@ -139,21 +139,21 @@
             // 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<Capability> caps = module.getCapabilities();
+            List<BundleCapabilityImpl> caps = module.getCapabilities();
             for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
             {
                 Wire wire = wires.get(wireIdx);
-                if (wire.getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (wire.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     for (int capIdx = 0;
                         (caps != null) && (capIdx < caps.size());
                         capIdx++)
                     {
-                        if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                            && wire.getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue()
-                                .equals(caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue()))
+                        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)))
                         {
-                            m_capSets.get(Capability.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
+                            m_capSets.get(BundleCapabilityImpl.PACKAGE_NAMESPACE).removeCapability(caps.get(capIdx));
                             break;
                         }
                     }
@@ -166,27 +166,27 @@
     // ResolverState methods.
     //
 
-    public synchronized SortedSet<Capability> getCandidates(
-        Requirement req, boolean obeyMandatory)
+    public synchronized SortedSet<BundleCapabilityImpl> getCandidates(
+        BundleRequirementImpl req, boolean obeyMandatory)
     {
         Module module = req.getModule();
-        SortedSet<Capability> result = new TreeSet<Capability>(new CandidateComparator());
+        SortedSet<BundleCapabilityImpl> result = new TreeSet<BundleCapabilityImpl>(new CandidateComparator());
 
         CapabilitySet capSet = m_capSets.get(req.getNamespace());
         if (capSet != null)
         {
-            Set<Capability> matches = capSet.match(req.getFilter(), obeyMandatory);
-            for (Capability cap : matches)
+            Set<BundleCapabilityImpl> matches = capSet.match(req.getFilter(), obeyMandatory);
+            for (BundleCapabilityImpl cap : matches)
             {
                 if (System.getSecurityManager() != null)
                 {
-                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE) && (
+                    if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) && (
                         !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
-                            new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                            new PackagePermission((String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
                             PackagePermission.EXPORTONLY)) ||
                             !((module == null) ||
                                 ((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
-                                    new PackagePermission((String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                                    new PackagePermission((String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
                                     cap.getModule().getBundle(),PackagePermission.IMPORT))
                             )))
                     {
@@ -195,7 +195,7 @@
                             continue;
                         }
                     }
-                    else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE) && (
+                    else if (req.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE) && (
                         !((BundleProtectionDomain) cap.getModule().getSecurityContext()).impliesDirect(
                             new BundlePermission(cap.getModule().getSymbolicName(), BundlePermission.PROVIDE)) ||
                             !((module == null) ||
@@ -205,7 +205,7 @@
                     {
                         continue;
                     }
-                    else if (req.getNamespace().equals(Capability.HOST_NAMESPACE) &&
+                    else if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE) &&
                         (!((BundleProtectionDomain) req.getModule().getSecurityContext())
                             .impliesDirect(new BundlePermission(
                                 req.getModule().getSymbolicName(),
@@ -219,7 +219,7 @@
                     }
                 }
 
-                if (req.getNamespace().equals(Capability.HOST_NAMESPACE)
+                if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE)
                     && cap.getModule().isResolved())
                 {
                     continue;
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 0ff2ca4..fa96d9b 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -22,15 +22,13 @@
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.*;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.resolver.Wire;
 
 import org.apache.felix.framework.util.MapToDictionary;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.*;
 import org.osgi.framework.BundleReference;
 
@@ -385,9 +383,15 @@
     // ServiceReference implementation
     //
 
-    class ServiceReferenceImpl implements ServiceReference, Capability
+    class ServiceReferenceImpl extends BundleCapabilityImpl implements ServiceReference
     {
-        private ServiceReferenceImpl() {}
+        private final ServiceReferenceMap m_map;
+
+        private ServiceReferenceImpl()
+        {
+            super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+            m_map = new ServiceReferenceMap();
+        }
 
         ServiceRegistrationImpl getRegistration()
         {
@@ -398,42 +402,40 @@
         // Capability methods.
         //
 
+        @Override
         public Module getModule()
         {
             throw new UnsupportedOperationException("Not supported yet.");
         }
 
+        @Override
         public String getNamespace()
         {
             return "service-reference";
         }
 
-        public Directive getDirective(String name)
+        @Override
+        public Map<String, String> getDirectives()
         {
-            return null;
+            return Collections.EMPTY_MAP;
         }
 
-        public List<Directive> getDirectives()
+        @Override
+        public Map<String, Object> getAttributes()
         {
-            return Collections.EMPTY_LIST;
+            return m_map;
         }
 
-        public Attribute getAttribute(String name)
-        {
-            Object value = ServiceRegistrationImpl.this.getProperty(name);
-            return (value == null) ? null : new Attribute(name, value, false);
-        }
-
-        public List<Attribute> getAttributes()
-        {
-            return Collections.EMPTY_LIST;
-        }
-
+        @Override
         public List<String> getUses()
         {
             return Collections.EMPTY_LIST;
         }
 
+        //
+        // ServiceReference methods.
+        //
+
         public Object getProperty(String s)
         {
             return ServiceRegistrationImpl.this.getProperty(s);
@@ -642,4 +644,67 @@
             return (id.compareTo(otherId) < 0) ? 1 : -1;
         }
     }
+
+    private class ServiceReferenceMap implements Map
+    {
+        public int size()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean isEmpty()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean containsKey(Object o)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean containsValue(Object o)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Object get(Object o)
+        {
+            return ServiceRegistrationImpl.this.getProperty((String) o);
+        }
+
+        public Object put(Object k, Object v)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Object remove(Object o)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void putAll(Map map)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void clear()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Set<Object> keySet()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Collection<Object> values()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public Set<Entry<Object, Object>> entrySet()
+        {
+            return Collections.EMPTY_SET;
+        }
+    }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index 4bbf780..b0a2cfa 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -19,9 +19,9 @@
 package org.apache.felix.framework;
 
 import java.util.*;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 
 import org.osgi.framework.*;
 import org.osgi.framework.hooks.service.*;
@@ -98,7 +98,7 @@
             // Get the bundles current registered services.
             ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
             m_regsMap.put(bundle, addServiceRegistration(regs, reg));
-            m_regCapSet.addCapability((Capability) reg.getReference());
+            m_regCapSet.addCapability((BundleCapabilityImpl) reg.getReference());
         }
 
         // Notify callback objects about registered service.
@@ -126,7 +126,7 @@
             // Now remove the registered service.
             ServiceRegistration[] regs = (ServiceRegistration[]) m_regsMap.get(bundle);
             m_regsMap.put(bundle, removeServiceRegistration(regs, reg));
-            m_regCapSet.removeCapability((Capability) reg.getReference());
+            m_regCapSet.removeCapability((BundleCapabilityImpl) reg.getReference());
         }
 
         // Notify callback objects about unregistering service.
@@ -208,7 +208,7 @@
         }
         // else just use the specified filter.
 
-        Set<Capability> matches = m_regCapSet.match(filter, false);
+        Set<BundleCapabilityImpl> matches = m_regCapSet.match(filter, false);
 
         return new ArrayList(matches);
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java
deleted file mode 100644
index f484d3e..0000000
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/Attribute.java
+++ /dev/null
@@ -1,53 +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.capabilityset;
-
-public class Attribute
-{
-    private final String m_name;
-    private final Object m_value;
-    private final boolean m_isMandatory;
-
-    public Attribute(String name, Object value, boolean isMandatory)
-    {
-        m_name = name;
-        m_value = value;
-        m_isMandatory = isMandatory;
-    }
-
-    public String getName()
-    {
-        return m_name;
-    }
-
-    public Object getValue()
-    {
-        return m_value;
-    }
-
-    public boolean isMandatory()
-    {
-        return m_isMandatory;
-    }
-
-    public String toString()
-    {
-        return m_name + "=" + m_value;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java
deleted file mode 100644
index 2a77b6a..0000000
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/Capability.java
+++ /dev/null
@@ -1,41 +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.capabilityset;
-
-import org.apache.felix.framework.resolver.Module;
-import java.util.List;
-
-public interface Capability
-{
-    static final String MODULE_NAMESPACE = "module";
-    static final String HOST_NAMESPACE = "host";
-    static final String PACKAGE_NAMESPACE = "package";
-    static final String SINGLETON_NAMESPACE = "singleton";
-
-    public static final String PACKAGE_ATTR = "package";
-    public static final String VERSION_ATTR = "version";
-
-    Module getModule();
-    String getNamespace();
-    Directive getDirective(String name);
-    List<Directive> getDirectives();
-    Attribute getAttribute(String name);
-    List<Attribute> getAttributes();
-    List<String> getUses();
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
index cd1990a..df3e1c0 100644
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/framework/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -32,45 +32,47 @@
 import java.util.TreeMap;
 import org.apache.felix.framework.util.SecureAction;
 import org.apache.felix.framework.util.StringComparator;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 
 public class CapabilitySet
 {
-    private final Map<String, Map<Object, Set<Capability>>> m_indices;
-    private final Set<Capability> m_capSet = new HashSet<Capability>();
+    private final Map<String, Map<Object, Set<BundleCapabilityImpl>>> m_indices;
+    private final Set<BundleCapabilityImpl> m_capSet = new HashSet<BundleCapabilityImpl>();
     private final static SecureAction m_secureAction = new SecureAction();
 
     public CapabilitySet(List<String> indexProps, boolean caseSensitive)
     {
         m_indices = (caseSensitive)
-            ? new TreeMap<String, Map<Object, Set<Capability>>>()
-            : new TreeMap<String, Map<Object, Set<Capability>>>(new StringComparator(false));
+            ? new TreeMap<String, Map<Object, Set<BundleCapabilityImpl>>>()
+            : new TreeMap<String, Map<Object, Set<BundleCapabilityImpl>>>(
+                new StringComparator(false));
         for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
         {
-            m_indices.put(indexProps.get(i), new HashMap<Object, Set<Capability>>());
+            m_indices.put(
+                indexProps.get(i), new HashMap<Object, Set<BundleCapabilityImpl>>());
         }
     }
 
-    public void addCapability(Capability cap)
+    public void addCapability(BundleCapabilityImpl cap)
     {
         m_capSet.add(cap);
 
         // Index capability.
-        for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+        for (Entry<String, Map<Object, Set<BundleCapabilityImpl>>> entry : m_indices.entrySet())
         {
-            Attribute capAttr = cap.getAttribute(entry.getKey());
-            if (capAttr != null)
+            Object value = cap.getAttributes().get(entry.getKey());
+            if (value != null)
             {
-                Object capValue = capAttr.getValue();
-                if (capValue.getClass().isArray())
+                if (value.getClass().isArray())
                 {
-                    capValue = convertArrayToList(capValue);
+                    value = convertArrayToList(value);
                 }
 
-                Map<Object, Set<Capability>> index = entry.getValue();
+                Map<Object, Set<BundleCapabilityImpl>> index = entry.getValue();
 
-                if (capValue instanceof Collection)
+                if (value instanceof Collection)
                 {
-                    Collection c = (Collection) capValue;
+                    Collection c = (Collection) value;
                     for (Object o : c)
                     {
                         indexCapability(index, cap, o);
@@ -78,44 +80,43 @@
                 }
                 else
                 {
-                    indexCapability(index, cap, capValue);
+                    indexCapability(index, cap, value);
                 }
             }
         }
     }
 
     private void indexCapability(
-        Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+        Map<Object, Set<BundleCapabilityImpl>> index, BundleCapabilityImpl cap, Object capValue)
     {
-        Set<Capability> caps = index.get(capValue);
+        Set<BundleCapabilityImpl> caps = index.get(capValue);
         if (caps == null)
         {
-            caps = new HashSet<Capability>();
+            caps = new HashSet<BundleCapabilityImpl>();
             index.put(capValue, caps);
         }
         caps.add(cap);
     }
 
-    public void removeCapability(Capability cap)
+    public void removeCapability(BundleCapabilityImpl cap)
     {
         if (m_capSet.remove(cap))
         {
-            for (Entry<String, Map<Object, Set<Capability>>> entry : m_indices.entrySet())
+            for (Entry<String, Map<Object, Set<BundleCapabilityImpl>>> entry : m_indices.entrySet())
             {
-                Attribute capAttr = cap.getAttribute(entry.getKey());
-                if (capAttr != null)
+                Object value = cap.getAttributes().get(entry.getKey());
+                if (value != null)
                 {
-                    Object capValue = capAttr.getValue();
-                    if (capValue.getClass().isArray())
+                    if (value.getClass().isArray())
                     {
-                        capValue = convertArrayToList(capValue);
+                        value = convertArrayToList(value);
                     }
 
-                    Map<Object, Set<Capability>> index = entry.getValue();
+                    Map<Object, Set<BundleCapabilityImpl>> index = entry.getValue();
 
-                    if (capValue instanceof Collection)
+                    if (value instanceof Collection)
                     {
-                        Collection c = (Collection) capValue;
+                        Collection c = (Collection) value;
                         for (Object o : c)
                         {
                             deindexCapability(index, cap, o);
@@ -123,7 +124,7 @@
                     }
                     else
                     {
-                        deindexCapability(index, cap, capValue);
+                        deindexCapability(index, cap, value);
                     }
                 }
             }
@@ -131,30 +132,30 @@
     }
 
     private void deindexCapability(
-        Map<Object, Set<Capability>> index, Capability cap, Object capValue)
+        Map<Object, Set<BundleCapabilityImpl>> index, BundleCapabilityImpl cap, Object value)
     {
-        Set<Capability> caps = index.get(capValue);
+        Set<BundleCapabilityImpl> caps = index.get(value);
         if (caps != null)
         {
             caps.remove(cap);
             if (caps.isEmpty())
             {
-                index.remove(capValue);
+                index.remove(value);
             }
         }
     }
 
-    public Set<Capability> match(SimpleFilter sf, boolean obeyMandatory)
+    public Set<BundleCapabilityImpl> match(SimpleFilter sf, boolean obeyMandatory)
     {
-        Set<Capability> matches = match(m_capSet, sf);
+        Set<BundleCapabilityImpl> matches = match(m_capSet, sf);
         return (obeyMandatory)
             ? matchMandatory(matches, sf)
             : matches;
     }
 
-    private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
+    private Set<BundleCapabilityImpl> match(Set<BundleCapabilityImpl> caps, SimpleFilter sf)
     {
-        Set<Capability> matches = new HashSet<Capability>();
+        Set<BundleCapabilityImpl> matches = new HashSet<BundleCapabilityImpl>();
 
         if (sf.getOperation() == SimpleFilter.MATCH_ALL)
         {
@@ -196,10 +197,10 @@
         }
         else
         {
-            Map<Object, Set<Capability>> index = m_indices.get(sf.getName());
+            Map<Object, Set<BundleCapabilityImpl>> index = m_indices.get(sf.getName());
             if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
             {
-                Set<Capability> existingCaps = index.get(sf.getValue());
+                Set<BundleCapabilityImpl> existingCaps = index.get(sf.getValue());
                 if (existingCaps != null)
                 {
                     matches.addAll(existingCaps);
@@ -208,13 +209,12 @@
             }
             else
             {
-                for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+                for (Iterator<BundleCapabilityImpl> it = caps.iterator(); it.hasNext(); )
                 {
-                    Capability cap = it.next();
-                    Attribute attr = cap.getAttribute(sf.getName());
-                    if (attr != null)
+                    BundleCapabilityImpl cap = it.next();
+                    Object lhs = cap.getAttributes().get(sf.getName());
+                    if (lhs != null)
                     {
-                        Object lhs = attr.getValue();
                         if (compare(lhs, sf.getValue(), sf.getOperation()))
                         {
                             matches.add(cap);
@@ -227,12 +227,12 @@
         return matches;
     }
 
-    public static boolean matches(Capability cap, SimpleFilter sf)
+    public static boolean matches(BundleCapabilityImpl cap, SimpleFilter sf)
     {
         return matchesInternal(cap, sf) && matchMandatory(cap, sf);
     }
 
-    private static boolean matchesInternal(Capability cap, SimpleFilter sf)
+    private static boolean matchesInternal(BundleCapabilityImpl cap, SimpleFilter sf)
     {
         boolean matched = true;
 
@@ -272,10 +272,9 @@
         else
         {
             matched = false;
-            Attribute attr = cap.getAttribute(sf.getName());
-            if (attr != null)
+            Object lhs = cap.getAttributes().get(sf.getName());
+            if (lhs != null)
             {
-                Object lhs = attr.getValue();
                 matched = compare(lhs, sf.getValue(), sf.getOperation());
             }
         }
@@ -283,11 +282,12 @@
         return matched;
     }
 
-    private static Set<Capability> matchMandatory(Set<Capability> caps, SimpleFilter sf)
+    private static Set<BundleCapabilityImpl> matchMandatory(
+        Set<BundleCapabilityImpl> caps, SimpleFilter sf)
     {
-        for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+        for (Iterator<BundleCapabilityImpl> it = caps.iterator(); it.hasNext(); )
         {
-            Capability cap = it.next();
+            BundleCapabilityImpl cap = it.next();
             if (!matchMandatory(cap, sf))
             {
                 it.remove();
@@ -296,13 +296,13 @@
         return caps;
     }
 
-    private static boolean matchMandatory(Capability cap, SimpleFilter sf)
+    private static boolean matchMandatory(BundleCapabilityImpl cap, SimpleFilter sf)
     {
-        List<Attribute> attrs = cap.getAttributes();
-        for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+        Map<String, Object> attrs = cap.getAttributes();
+        for (Entry<String, Object> entry : attrs.entrySet())
         {
-            if (attrs.get(attrIdx).isMandatory()
-                && !matchMandatory(attrs.get(attrIdx), sf))
+            if (cap.isAttributeMandatory(entry.getKey())
+                && !matchMandatoryAttrbute(entry.getKey(), sf))
             {
                 return false;
             }
@@ -310,9 +310,9 @@
         return true;
     }
 
-    private static boolean matchMandatory(Attribute attr, SimpleFilter sf)
+    private static boolean matchMandatoryAttrbute(String attrName, SimpleFilter sf)
     {
-        if ((sf.getName() != null) && sf.getName().equals(attr.getName()))
+        if ((sf.getName() != null) && sf.getName().equals(attrName))
         {
             return true;
         }
@@ -323,7 +323,7 @@
             {
                 SimpleFilter sf2 = (SimpleFilter) list.get(i);
                 if ((sf2.getName() != null)
-                    && sf2.getName().equals(attr.getName()))
+                    && sf2.getName().equals(attrName))
                 {
                     return true;
                 }
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java
deleted file mode 100644
index 0541d2b..0000000
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/Directive.java
+++ /dev/null
@@ -1,46 +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.capabilityset;
-
-public class Directive
-{
-    private final String m_name;
-    private final Object m_value;
-
-    public Directive(String name, Object value)
-    {
-        m_name = name;
-        m_value = value;
-    }
-
-    public String getName()
-    {
-        return m_name;
-    }
-
-    public Object getValue()
-    {
-        return m_value;
-    }
-
-    public String toString()
-    {
-        return m_name + "=" + m_value;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java b/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java
deleted file mode 100644
index 65ee7e7..0000000
--- a/framework/src/main/java/org/apache/felix/framework/capabilityset/Requirement.java
+++ /dev/null
@@ -1,32 +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.capabilityset;
-
-import java.util.List;
-import org.apache.felix.framework.resolver.Module;
-
-public interface Requirement
-{
-    Module getModule();
-    String getNamespace();
-    SimpleFilter getFilter();
-    boolean isOptional();
-    Directive getDirective(String name);
-    List<Directive> getDirectives();
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
index 6e6387f..c42c6bd 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/CandidateComparator.java
@@ -19,13 +19,13 @@
 package org.apache.felix.framework.resolver;
 
 import java.util.Comparator;
-import org.apache.felix.framework.capabilityset.Capability;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
-public class CandidateComparator implements Comparator<Capability>
+public class CandidateComparator implements Comparator<BundleCapabilityImpl>
 {
-    public int compare(Capability cap1, Capability cap2)
+    public int compare(BundleCapabilityImpl cap1, BundleCapabilityImpl cap2)
     {
         // First check resolved state, since resolved capabilities have priority
         // over unresolved ones. Compare in reverse order since we want to sort
@@ -41,37 +41,36 @@
         }
 
         // Compare module capabilities.
-        if ((c == 0) && cap1.getNamespace().equals(Capability.MODULE_NAMESPACE))
+        if ((c == 0) && cap1.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
         {
-            c = ((Comparable) cap1.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
-                .getValue()).compareTo(cap2.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
-                    .getValue());
+            c = ((Comparable) cap1.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                .compareTo(cap2.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE));
             if (c == 0)
             {
-                Version v1 = (cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+                Version v1 = (!cap1.getAttributes().containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE))
                     ? Version.emptyVersion
-                    : (Version) cap1.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
-                Version v2 = (cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE) == null)
+                    : (Version) cap1.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+                Version v2 = (!cap2.getAttributes().containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE))
                     ? Version.emptyVersion
-                    : (Version) cap2.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE).getValue();
+                    : (Version) cap2.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
                 // Compare these in reverse order, since we want
                 // highest version to have priority.
                 c = v2.compareTo(v1);
             }
         }
         // Compare package capabilities.
-        else if ((c == 0) && cap1.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        else if ((c == 0) && cap1.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
-            c = ((Comparable) cap1.getAttribute(Capability.PACKAGE_ATTR).getValue())
-                .compareTo(cap2.getAttribute(Capability.PACKAGE_ATTR).getValue());
+            c = ((Comparable) cap1.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR))
+                .compareTo(cap2.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
             if (c == 0)
             {
-                Version v1 = (cap1.getAttribute(Capability.VERSION_ATTR) == null)
+                Version v1 = (!cap1.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
                     ? Version.emptyVersion
-                    : (Version) cap1.getAttribute(Capability.VERSION_ATTR).getValue();
-                Version v2 = (cap2.getAttribute(Capability.VERSION_ATTR) == null)
+                    : (Version) cap1.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
+                Version v2 = (!cap2.getAttributes().containsKey(BundleCapabilityImpl.VERSION_ATTR))
                     ? Version.emptyVersion
-                    : (Version) cap2.getAttribute(Capability.VERSION_ATTR).getValue();
+                    : (Version) cap2.getAttributes().get(BundleCapabilityImpl.VERSION_ATTR);
                 // Compare these in reverse order, since we want
                 // highest version to have priority.
                 c = v2.compareTo(v1);
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 b99d541..269a12d 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
@@ -30,11 +30,10 @@
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.resolver.Resolver.ResolverState;
 import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
@@ -45,14 +44,15 @@
     // Set of all candidate modules.
     private final Set<Module> m_candidateModules;
     // Maps a capability to requirements that match it.
-    private final Map<Capability, Set<Requirement>> m_dependentMap;
+    private final Map<BundleCapabilityImpl, Set<BundleRequirementImpl>> m_dependentMap;
     // Maps a requirement to the capability it matches.
-    private final Map<Requirement, SortedSet<Capability>> m_candidateMap;
+    private final Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> m_candidateMap;
     // Maps a host capability to a map containing its potential fragments;
     // the fragment map maps a fragment symbolic name to a map that maps
     // a version to a list of fragments requirements matching that symbolic
     // name and version.
-    private final Map<Capability, Map<String, Map<Version, List<Requirement>>>> m_hostFragments;
+    private final Map<BundleCapabilityImpl,
+        Map<String, Map<Version, List<BundleRequirementImpl>>>> m_hostFragments;
     // Maps a module to its associated wrapped module; this only happens
     // when a module being resolved has fragments to attach to it.
     private final Map<Module, HostModule> m_allWrappedHosts;
@@ -73,9 +73,9 @@
     private Candidates(
         Module root,
         Set<Module> candidateModules,
-        Map<Capability, Set<Requirement>> dependentMap,
-        Map<Requirement, SortedSet<Capability>> candidateMap,
-        Map<Capability, Map<String, Map<Version, List<Requirement>>>> hostFragments,
+        Map<BundleCapabilityImpl, Set<BundleRequirementImpl>> dependentMap,
+        Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> candidateMap,
+        Map<BundleCapabilityImpl, Map<String, Map<Version, List<BundleRequirementImpl>>>> hostFragments,
         Map<Module, HostModule> wrappedHosts, Map<Module, Object> populateResultCache,
         boolean fragmentsPresent)
     {
@@ -98,10 +98,10 @@
     {
         m_root = root;
         m_candidateModules = new HashSet<Module>();
-        m_dependentMap = new HashMap<Capability, Set<Requirement>>();
-        m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
+        m_dependentMap = new HashMap<BundleCapabilityImpl, Set<BundleRequirementImpl>>();
+        m_candidateMap = new HashMap<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>>();
         m_hostFragments =
-            new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
+            new HashMap<BundleCapabilityImpl, Map<String, Map<Version, List<BundleRequirementImpl>>>>();
         m_allWrappedHosts = new HashMap<Module, HostModule>();
         m_populateResultCache = new HashMap<Module, Object>();
 
@@ -119,14 +119,14 @@
      * @param candidates the potential candidates matching the requirement.
     **/
     public Candidates(ResolverState state, Module root,
-        Requirement req, SortedSet<Capability> candidates)
+        BundleRequirementImpl req, SortedSet<BundleCapabilityImpl> candidates)
     {
         m_root = root;
         m_candidateModules = new HashSet<Module>();
-        m_dependentMap = new HashMap<Capability, Set<Requirement>>();
-        m_candidateMap = new HashMap<Requirement, SortedSet<Capability>>();
+        m_dependentMap = new HashMap<BundleCapabilityImpl, Set<BundleRequirementImpl>>();
+        m_candidateMap = new HashMap<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>>();
         m_hostFragments =
-            new HashMap<Capability, Map<String, Map<Version, List<Requirement>>>>();
+            new HashMap<BundleCapabilityImpl, Map<String, Map<Version, List<BundleRequirementImpl>>>>();
         m_allWrappedHosts = new HashMap<Module, HostModule>();
         m_populateResultCache = new HashMap<Module, Object>();
 
@@ -163,11 +163,11 @@
 
         // Keeps track of the candidates we've already calculated for the
         // current module's requirements.
-        Map<Requirement, SortedSet<Capability>> localCandidateMap = null;
+        Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> localCandidateMap = null;
 
         // Keeps track of the current module's requirements for which we
         // haven't yet found candidates.
-        List<Requirement> remainingReqs = null;
+        List<BundleRequirementImpl> remainingReqs = null;
 
         // Get the cache value for the current module.
         Object cacheValue = m_populateResultCache.get(module);
@@ -226,14 +226,15 @@
         // If we have requirements remaining, then find candidates for them.
         while (remainingReqs.size() > 0)
         {
-            Requirement req = remainingReqs.remove(0);
+            BundleRequirementImpl req = remainingReqs.remove(0);
 
             // Get satisfying candidates and populate their candidates if necessary.
             ResolveException rethrow = null;
-            SortedSet<Capability> candidates = state.getCandidates(req, true);
-            for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
+            SortedSet<BundleCapabilityImpl> candidates = state.getCandidates(req, true);
+            for (Iterator<BundleCapabilityImpl> itCandCap = candidates.iterator();
+                itCandCap.hasNext(); )
             {
-                Capability candCap = itCandCap.next();
+                BundleCapabilityImpl candCap = itCandCap.next();
 
                 // If the candidate module is a fragment, then always attempt
                 // to populate candidates for its dependency, since it must be
@@ -328,14 +329,14 @@
                 if (cacheValue == null)
                 {
                     // Create a modifiable list of the module's requirements.
-                    List<Requirement> remainingReqs = new ArrayList(module.getRequirements());
+                    List<BundleRequirementImpl> remainingReqs = new ArrayList(module.getRequirements());
 
                     // Find the host requirement.
-                    Requirement hostReq = null;
-                    for (Iterator<Requirement> it = remainingReqs.iterator(); it.hasNext(); )
+                    BundleRequirementImpl hostReq = null;
+                    for (Iterator<BundleRequirementImpl> it = remainingReqs.iterator(); it.hasNext(); )
                     {
-                        Requirement r = it.next();
-                        if (r.getNamespace().equals(Capability.HOST_NAMESPACE))
+                        BundleRequirementImpl r = it.next();
+                        if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
                         {
                             hostReq = r;
                             it.remove();
@@ -343,10 +344,10 @@
                     }
 
                     // Get candidates hosts and keep any that have been populated.
-                    SortedSet<Capability> hosts = state.getCandidates(hostReq, false);
-                    for (Iterator<Capability> it = hosts.iterator(); it.hasNext(); )
+                    SortedSet<BundleCapabilityImpl> hosts = state.getCandidates(hostReq, false);
+                    for (Iterator<BundleCapabilityImpl> it = hosts.iterator(); it.hasNext(); )
                     {
-                        Capability host = it.next();
+                        BundleCapabilityImpl host = it.next();
                         if (!isPopulated(host.getModule()))
                         {
                             it.remove();
@@ -376,7 +377,8 @@
 
                     // Create a local map for populating candidates first, just in case
                     // the module is not resolvable.
-                    Map<Requirement, SortedSet<Capability>> localCandidateMap = new HashMap();
+                    Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> localCandidateMap =
+                        new HashMap<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>>();
 
                     // Add the discovered host candidates to the local candidate map.
                     localCandidateMap.put(hostReq, hosts);
@@ -410,13 +412,14 @@
         // the candidates for the matching dynamic requirement. Get the
         // matching candidates and populate their candidates if necessary.
         ResolveException rethrow = null;
-        Entry<Requirement, SortedSet<Capability>> entry =
+        Entry<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> entry =
             m_candidateMap.entrySet().iterator().next();
-        Requirement dynReq = entry.getKey();
-        SortedSet<Capability> candidates = entry.getValue();
-        for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
+        BundleRequirementImpl dynReq = entry.getKey();
+        SortedSet<BundleCapabilityImpl> candidates = entry.getValue();
+        for (Iterator<BundleCapabilityImpl> itCandCap = candidates.iterator();
+            itCandCap.hasNext(); )
         {
-            Capability candCap = itCandCap.next();
+            BundleCapabilityImpl candCap = itCandCap.next();
             if (!candCap.getModule().isResolved())
             {
                 try
@@ -453,9 +456,9 @@
      * @param req the requirement to add.
      * @param candidates the candidates matching the requirement.
     **/
-    private void add(Requirement req, SortedSet<Capability> candidates)
+    private void add(BundleRequirementImpl req, SortedSet<BundleCapabilityImpl> candidates)
     {
-        if (req.getNamespace().equals(Capability.HOST_NAMESPACE))
+        if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
         {
             m_fragmentsPresent = true;
         }
@@ -466,7 +469,7 @@
         // Make a list of all candidate modules for determining singetons.
         // Add the requirement as a dependent on the candidates. Keep track
         // of fragments for hosts.
-        for (Capability cap : candidates)
+        for (BundleCapabilityImpl cap : candidates)
         {
             // Remember the module for all capabilities so we can
             // determine which ones are singletons.
@@ -480,9 +483,9 @@
      * be further modified by the caller.
      * @param candidates the bulk requirements and candidates to add.
     **/
-    private void add(Map<Requirement, SortedSet<Capability>> candidates)
+    private void add(Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> candidates)
     {
-        for (Entry<Requirement, SortedSet<Capability>> entry : candidates.entrySet())
+        for (Entry<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> entry : candidates.entrySet())
         {
             add(entry.getKey(), entry.getValue());
         }
@@ -506,7 +509,7 @@
      * @param req the requirement whose candidates are desired.
      * @return the matching candidates or null.
     **/
-    public SortedSet<Capability> getCandidates(Requirement req)
+    public SortedSet<BundleCapabilityImpl> getCandidates(BundleRequirementImpl req)
     {
         return m_candidateMap.get(req);
     }
@@ -626,22 +629,24 @@
         //      with host's attached fragment capabilities.
 
         // Steps 1 and 2
-        List<HostModule> wrappedHosts = new ArrayList<HostModule>();
+        List<HostModule> hostModules = new ArrayList<HostModule>();
         List<Module> unselectedFragments = new ArrayList<Module>();
-        for (Entry<Capability, Map<String, Map<Version, List<Requirement>>>> hostEntry :
-            m_hostFragments.entrySet())
+        for (Entry<BundleCapabilityImpl, Map<String, Map<Version, List<BundleRequirementImpl>>>>
+            hostEntry : m_hostFragments.entrySet())
         {
             // Step 1
-            Capability hostCap = hostEntry.getKey();
-            Map<String, Map<Version, List<Requirement>>> fragments = hostEntry.getValue();
+            BundleCapabilityImpl hostCap = hostEntry.getKey();
+            Map<String, Map<Version, List<BundleRequirementImpl>>> fragments
+                = hostEntry.getValue();
             List<Module> selectedFragments = new ArrayList<Module>();
-            for (Entry<String, Map<Version, List<Requirement>>> fragEntry : fragments.entrySet())
+            for (Entry<String, Map<Version, List<BundleRequirementImpl>>> fragEntry
+                : fragments.entrySet())
             {
                 boolean isFirst = true;
-                for (Entry<Version, List<Requirement>> versionEntry
+                for (Entry<Version, List<BundleRequirementImpl>> versionEntry
                     : fragEntry.getValue().entrySet())
                 {
-                    for (Requirement hostReq : versionEntry.getValue())
+                    for (BundleRequirementImpl hostReq : versionEntry.getValue())
                     {
                         // Select the highest version of the fragment that
                         // is not removal pending.
@@ -658,7 +663,7 @@
                         else
                         {
                             m_dependentMap.get(hostCap).remove(hostReq);
-                            SortedSet<Capability> hosts = m_candidateMap.get(hostReq);
+                            SortedSet<BundleCapabilityImpl> hosts = m_candidateMap.get(hostReq);
                             hosts.remove(hostCap);
                             if (hosts.isEmpty())
                             {
@@ -671,7 +676,7 @@
 
             // Step 2
             HostModule wrappedHost = new HostModule(hostCap.getModule(), selectedFragments);
-            wrappedHosts.add(wrappedHost);
+            hostModules.add(wrappedHost);
             m_allWrappedHosts.put(hostCap.getModule(), wrappedHost);
         }
 
@@ -682,19 +687,19 @@
         }
 
         // Step 4
-        for (HostModule wrappedHost : wrappedHosts)
+        for (HostModule hostModule : hostModules)
         {
             // Replaces capabilities from fragments with the capabilities
             // from the merged host.
-            for (Capability c : wrappedHost.getCapabilities())
+            for (BundleCapabilityImpl c : hostModule.getCapabilities())
             {
-                Set<Requirement> dependents =
+                Set<BundleRequirementImpl> dependents =
                     m_dependentMap.get(((HostedCapability) c).getDeclaredCapability());
                 if (dependents != null)
                 {
-                    for (Requirement r : dependents)
+                    for (BundleRequirementImpl r : dependents)
                     {
-                        Set<Capability> cands = m_candidateMap.get(r);
+                        Set<BundleCapabilityImpl> cands = m_candidateMap.get(r);
                         cands.remove(((HostedCapability) c).getDeclaredCapability());
                         cands.add(c);
                     }
@@ -704,13 +709,13 @@
             // 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 (Requirement r : wrappedHost.getRequirements())
+            for (BundleRequirementImpl r : hostModule.getRequirements())
             {
-                SortedSet<Capability> cands =
+                SortedSet<BundleCapabilityImpl> cands =
                     m_candidateMap.get(((HostedRequirement) r).getDeclaredRequirement());
                 if (cands != null)
                 {
-                    m_candidateMap.put(r, new TreeSet<Capability>(cands));
+                    m_candidateMap.put(r, new TreeSet<BundleCapabilityImpl>(cands));
                 }
             }
         }
@@ -718,43 +723,44 @@
 
     private void populateDependents()
     {
-        for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
+        for (Entry<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> entry
+            : m_candidateMap.entrySet())
         {
-            Requirement req = entry.getKey();
-            SortedSet<Capability> caps = entry.getValue();
-            for (Capability cap : caps)
+            BundleRequirementImpl req = entry.getKey();
+            SortedSet<BundleCapabilityImpl> caps = entry.getValue();
+            for (BundleCapabilityImpl cap : caps)
             {
                 // Record the requirement as dependent on the capability.
-                Set<Requirement> dependents = m_dependentMap.get(cap);
+                Set<BundleRequirementImpl> dependents = m_dependentMap.get(cap);
                 if (dependents == null)
                 {
-                    dependents = new HashSet<Requirement>();
+                    dependents = new HashSet<BundleRequirementImpl>();
                     m_dependentMap.put(cap, dependents);
                 }
                 dependents.add(req);
 
                 // Keep track of hosts and associated fragments.
-                if (req.getNamespace().equals(Capability.HOST_NAMESPACE))
+                if (req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
                 {
-                    Map<String, Map<Version, List<Requirement>>>
+                    Map<String, Map<Version, List<BundleRequirementImpl>>>
                         fragments = m_hostFragments.get(cap);
                     if (fragments == null)
                     {
-                        fragments = new HashMap<String, Map<Version, List<Requirement>>>();
+                        fragments = new HashMap<String, Map<Version, List<BundleRequirementImpl>>>();
                         m_hostFragments.put(cap, fragments);
                     }
-                    Map<Version, List<Requirement>> fragmentVersions =
+                    Map<Version, List<BundleRequirementImpl>> fragmentVersions =
                         fragments.get(req.getModule().getSymbolicName());
                     if (fragmentVersions == null)
                     {
                         fragmentVersions =
-                            new TreeMap<Version, List<Requirement>>(Collections.reverseOrder());
+                            new TreeMap<Version, List<BundleRequirementImpl>>(Collections.reverseOrder());
                         fragments.put(req.getModule().getSymbolicName(), fragmentVersions);
                     }
-                    List<Requirement> actual = fragmentVersions.get(req.getModule().getVersion());
+                    List<BundleRequirementImpl> actual = fragmentVersions.get(req.getModule().getVersion());
                     if (actual == null)
                     {
-                        actual = new ArrayList<Requirement>();
+                        actual = new ArrayList<BundleRequirementImpl>();
                         fragmentVersions.put(req.getModule().getVersion(), actual);
                     }
                     actual.add(req);
@@ -803,12 +809,12 @@
     **/
     private void remove(Module m, Set<Module> unresolvedModules) throws ResolveException
     {
-        for (Requirement r : m.getRequirements())
+        for (BundleRequirementImpl r : m.getRequirements())
         {
             remove(r);
         }
 
-        for (Capability c : m.getCapabilities())
+        for (BundleCapabilityImpl c : m.getCapabilities())
         {
             remove(c, unresolvedModules);
         }
@@ -818,16 +824,16 @@
      * Removes a requirement from the internal data structures.
      * @param req the requirement to remove.
     **/
-    private void remove(Requirement req)
+    private void remove(BundleRequirementImpl req)
     {
-        boolean isFragment = req.getNamespace().equals(Capability.HOST_NAMESPACE);
+        boolean isFragment = req.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE);
 
-        SortedSet<Capability> candidates = m_candidateMap.remove(req);
+        SortedSet<BundleCapabilityImpl> candidates = m_candidateMap.remove(req);
         if (candidates != null)
         {
-            for (Capability cap : candidates)
+            for (BundleCapabilityImpl cap : candidates)
             {
-                Set<Requirement> dependents = m_dependentMap.get(cap);
+                Set<BundleRequirementImpl> dependents = m_dependentMap.get(cap);
                 if (dependents != null)
                 {
                     dependents.remove(req);
@@ -835,15 +841,15 @@
 
                 if (isFragment)
                 {
-                    Map<String, Map<Version, List<Requirement>>>
+                    Map<String, Map<Version, List<BundleRequirementImpl>>>
                         fragments = m_hostFragments.get(cap);
                     if (fragments != null)
                     {
-                        Map<Version, List<Requirement>> fragmentVersions =
+                        Map<Version, List<BundleRequirementImpl>> fragmentVersions =
                             fragments.get(req.getModule().getSymbolicName());
                         if (fragmentVersions != null)
                         {
-                            List<Requirement> actual =
+                            List<BundleRequirementImpl> actual =
                                 fragmentVersions.get(req.getModule().getVersion());
                             if (actual != null)
                             {
@@ -877,14 +883,15 @@
      *        also need to be removed.
      * @throws ResolveException if removing the module caused the resolve to fail.
     **/
-    private void remove(Capability c, Set<Module> unresolvedModules) throws ResolveException
+    private void remove(BundleCapabilityImpl c, Set<Module> unresolvedModules)
+        throws ResolveException
     {
-        Set<Requirement> dependents = m_dependentMap.remove(c);
+        Set<BundleRequirementImpl> dependents = m_dependentMap.remove(c);
         if (dependents != null)
         {
-            for (Requirement r : dependents)
+            for (BundleRequirementImpl r : dependents)
             {
-                SortedSet<Capability> candidates = m_candidateMap.get(r);
+                SortedSet<BundleCapabilityImpl> candidates = m_candidateMap.get(r);
                 candidates.remove(c);
                 if (candidates.isEmpty())
                 {
@@ -912,19 +919,21 @@
     **/
     public Candidates copy()
     {
-        Map<Capability, Set<Requirement>> dependentMap =
-            new HashMap<Capability, Set<Requirement>>();
-        for (Entry<Capability, Set<Requirement>> entry : m_dependentMap.entrySet())
+        Map<BundleCapabilityImpl, Set<BundleRequirementImpl>> dependentMap =
+            new HashMap<BundleCapabilityImpl, Set<BundleRequirementImpl>>();
+        for (Entry<BundleCapabilityImpl, Set<BundleRequirementImpl>> entry : m_dependentMap.entrySet())
         {
-            Set<Requirement> dependents = new HashSet<Requirement>(entry.getValue());
+            Set<BundleRequirementImpl> dependents = new HashSet<BundleRequirementImpl>(entry.getValue());
             dependentMap.put(entry.getKey(), dependents);
         }
 
-        Map<Requirement, SortedSet<Capability>> candidateMap =
-            new HashMap<Requirement, SortedSet<Capability>>();
-        for (Entry<Requirement, SortedSet<Capability>> entry : m_candidateMap.entrySet())
+        Map<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> candidateMap =
+            new HashMap<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>>();
+        for (Entry<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> entry
+            : m_candidateMap.entrySet())
         {
-            SortedSet<Capability> candidates = new TreeSet<Capability>(entry.getValue());
+            SortedSet<BundleCapabilityImpl> candidates =
+                new TreeSet<BundleCapabilityImpl>(entry.getValue());
             candidateMap.put(entry.getKey(), candidates);
         }
 
@@ -938,7 +947,7 @@
     {
         // Create set of all modules from requirements.
         Set<Module> modules = new HashSet();
-        for (Entry<Requirement, SortedSet<Capability>> entry
+        for (Entry<BundleRequirementImpl, SortedSet<BundleCapabilityImpl>> entry
             : m_candidateMap.entrySet())
         {
             modules.add(entry.getKey().getModule());
@@ -949,17 +958,17 @@
         {
             System.out.println("  " + module
                  + " (" + (module.isResolved() ? "RESOLVED)" : "UNRESOLVED)"));
-            for (Requirement req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getRequirements())
             {
-                Set<Capability> candidates = m_candidateMap.get(req);
+                Set<BundleCapabilityImpl> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
                 }
             }
-            for (Requirement req : module.getDynamicRequirements())
+            for (BundleRequirementImpl req : module.getDynamicRequirements())
             {
-                Set<Capability> candidates = m_candidateMap.get(req);
+                Set<BundleCapabilityImpl> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
@@ -978,21 +987,17 @@
     **/
     private static boolean isSingleton(Module module)
     {
-        final List<Capability> modCaps =
+        final List<BundleCapabilityImpl> modCaps =
             Util.getCapabilityByNamespace(
-                module, Capability.MODULE_NAMESPACE);
+                module, BundleCapabilityImpl.MODULE_NAMESPACE);
         if (modCaps == null || modCaps.isEmpty())
         {
             return false;
         }
-        final List<Directive> dirs = modCaps.get(0).getDirectives();
-        for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.size()); dirIdx++)
+        String value = modCaps.get(0).getDirectives().get(Constants.SINGLETON_DIRECTIVE);
+        if (value != null)
         {
-            if (dirs.get(dirIdx).getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
-                && Boolean.valueOf((String) dirs.get(dirIdx).getValue()))
-            {
-                return true;
-            }
+            return Boolean.valueOf(value);
         }
         return false;
     }
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 819eeef..dbd8b9f 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
@@ -26,9 +26,9 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
 
@@ -36,8 +36,8 @@
 {
     private final Module m_host;
     private final List<Module> m_fragments;
-    private List<Capability> m_cachedCapabilities = null;
-    private List<Requirement> m_cachedRequirements = null;
+    private List<BundleCapabilityImpl> m_cachedCapabilities = null;
+    private List<BundleRequirementImpl> m_cachedRequirements = null;
 
     public HostModule(Module module, List<Module> fragments)
     {
@@ -60,14 +60,14 @@
         return m_host.getId();
     }
 
-    public List<Capability> getCapabilities()
+    public List<BundleCapabilityImpl> getCapabilities()
     {
         if (m_cachedCapabilities == null)
         {
-            List<Capability> capList = new ArrayList<Capability>();
+            List<BundleCapabilityImpl> capList = new ArrayList<BundleCapabilityImpl>();
 
             // Wrap host capabilities.
-            List<Capability> caps = m_host.getCapabilities();
+            List<BundleCapabilityImpl> caps = m_host.getCapabilities();
             for (int capIdx = 0;
                 (caps != null) && (capIdx < caps.size());
                 capIdx++)
@@ -86,7 +86,7 @@
                     (caps != null) && (capIdx < caps.size());
                     capIdx++)
                 {
-                    if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
                         capList.add(
                             new HostedCapability(this, caps.get(capIdx)));
@@ -98,14 +98,14 @@
         return m_cachedCapabilities;
     }
 
-    public List<Requirement> getRequirements()
+    public List<BundleRequirementImpl> getRequirements()
     {
         if (m_cachedRequirements == null)
         {
-            List<Requirement> reqList = new ArrayList<Requirement>();
+            List<BundleRequirementImpl> reqList = new ArrayList<BundleRequirementImpl>();
 
             // Wrap host requirements.
-            List<Requirement> reqs = m_host.getRequirements();
+            List<BundleRequirementImpl> reqs = m_host.getRequirements();
             for (int reqIdx = 0;
                 (reqs != null) && (reqIdx < reqs.size());
                 reqIdx++)
@@ -124,8 +124,8 @@
                     (reqs != null) && (reqIdx < reqs.size());
                     reqIdx++)
                 {
-                    if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                        || reqs.get(reqIdx).getNamespace().equals(Capability.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)));
@@ -162,7 +162,7 @@
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    public List<Requirement> getDynamicRequirements()
+    public List<BundleRequirementImpl> getDynamicRequirements()
     {
         throw new UnsupportedOperationException("Not supported yet.");
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
index 04c68b7..f5666be 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
@@ -19,17 +19,17 @@
 package org.apache.felix.framework.resolver;
 
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
+import java.util.Map;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 
-public class HostedCapability implements Capability
+public class HostedCapability extends BundleCapabilityImpl
 {
     private final Module m_host;
-    private final Capability m_cap;
+    private final BundleCapabilityImpl m_cap;
 
-    public HostedCapability(Module module, Capability cap)
+    public HostedCapability(Module module, BundleCapabilityImpl cap)
     {
+        super(module, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
         m_host = module;
         m_cap = cap;
     }
@@ -66,41 +66,36 @@
         return hash;
     }
 
-    public Capability getDeclaredCapability()
+    public BundleCapabilityImpl getDeclaredCapability()
     {
         return m_cap;
     }
 
+    @Override
     public Module getModule()
     {
         return m_host;
     }
 
+    @Override
     public String getNamespace()
     {
         return m_cap.getNamespace();
     }
 
-    public Directive getDirective(String name)
-    {
-        return m_cap.getDirective(name);
-    }
-
-    public List<Directive> getDirectives()
+    @Override
+    public Map<String, String> getDirectives()
     {
         return m_cap.getDirectives();
     }
 
-    public Attribute getAttribute(String name)
-    {
-        return m_cap.getAttribute(name);
-    }
-
-    public List<Attribute> getAttributes()
+    @Override
+    public Map<String, Object> getAttributes()
     {
         return m_cap.getAttributes();
     }
 
+    @Override
     public List<String> getUses()
     {
         return m_cap.getUses();
@@ -113,10 +108,10 @@
         {
             return getAttributes().toString();
         }
-        if (getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
             return "[" + m_host + "] "
-                + getNamespace() + "; " + getAttribute(Capability.PACKAGE_ATTR);
+                + getNamespace() + "; " + getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
         }
         return "[" + m_host + "] " + getNamespace() + "; " + getAttributes();
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java b/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
index 10f6f53..2f54284 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
@@ -18,18 +18,18 @@
  */
 package org.apache.felix.framework.resolver;
 
-import java.util.List;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.Requirement;
+import java.util.Map;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
-public class HostedRequirement implements Requirement
+public class HostedRequirement extends BundleRequirementImpl
 {
     private final Module m_host;
-    private final Requirement m_req;
+    private final BundleRequirementImpl m_req;
 
-    public HostedRequirement(Module module, Requirement req)
+    public HostedRequirement(Module module, BundleRequirementImpl req)
     {
+        super(module, req.getNamespace(), req.getDirectives(), req.getAttributes());
         m_host = module;
         m_req = req;
     }
@@ -66,41 +66,48 @@
         return hash;
     }
 
-    public Requirement getDeclaredRequirement()
+    public BundleRequirementImpl getDeclaredRequirement()
     {
         return m_req;
     }
 
+    @Override
     public Module getModule()
     {
         return m_host;
     }
 
+    @Override
     public String getNamespace()
     {
         return m_req.getNamespace();
     }
 
+    @Override
     public SimpleFilter getFilter()
     {
         return m_req.getFilter();
     }
 
+    @Override
     public boolean isOptional()
     {
         return m_req.isOptional();
     }
 
-    public Directive getDirective(String name)
-    {
-        return m_req.getDirective(name);
-    }
-
-    public List<Directive> getDirectives()
+    @Override
+    public Map<String, String> getDirectives()
     {
         return m_req.getDirectives();
     }
 
+    @Override
+    public Map<String, Object> getAttributes()
+    {
+        return m_req.getAttributes();
+    }
+
+    @Override
     public String toString()
     {
         return "[" + m_host + "] " + getNamespace() + "; " + getFilter().toString();
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 7d9f84f..465dac7 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
@@ -24,9 +24,9 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Version;
 
@@ -40,9 +40,9 @@
     boolean isExtension();
     String getSymbolicName();
     Version getVersion();
-    List<Capability> getCapabilities();
-    List<Requirement> getRequirements();
-    List<Requirement> getDynamicRequirements();
+    List<BundleCapabilityImpl> getCapabilities();
+    List<BundleRequirementImpl> getRequirements();
+    List<BundleRequirementImpl> getDynamicRequirements();
     List<R4Library> getNativeLibraries();
     int getDeclaredActivationPolicy();
 
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
index 8e69cd3..fd423d2 100755
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolveException.java
@@ -18,18 +18,18 @@
  */
 package org.apache.felix.framework.resolver;
 
-import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 public class ResolveException extends RuntimeException
 {
     private final Module m_module;
-    private final Requirement m_req;
+    private final BundleRequirementImpl m_req;
 
     /**
      * Constructs an instance of <code>ResolveException</code> with the specified detail message.
      * @param msg the detail message.
      */
-    public ResolveException(String msg, Module module, Requirement req)
+    public ResolveException(String msg, Module module, BundleRequirementImpl req)
     {
         super(msg);
         m_module = module;
@@ -41,7 +41,7 @@
         return m_module;
     }
 
-    public Requirement getRequirement()
+    public BundleRequirementImpl getRequirement()
     {
         return m_req;
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
index 9d65b4f..e7c7892 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -22,8 +22,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 public interface Resolver
 {
@@ -33,7 +33,8 @@
 
     public static interface ResolverState
     {
-        SortedSet<Capability> getCandidates(Requirement req, boolean obeyMandatory);
+        SortedSet<BundleCapabilityImpl> getCandidates(
+            BundleRequirementImpl req, boolean obeyMandatory);
         void checkExecutionEnvironment(Module module) throws ResolveException;
         void checkNativeLibraries(Module module) throws ResolveException;
     }
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 04dca7d..ef0d694 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -29,13 +29,10 @@
 import java.util.Set;
 import java.util.SortedSet;
 import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.RequirementImpl;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Constants;
 
 public class ResolverImpl implements Resolver
@@ -88,7 +85,7 @@
 
                     // If the requested module is a fragment, then
                     // ultimately we will verify the host.
-                    Requirement hostReq = getHostRequirement(module);
+                    BundleRequirementImpl hostReq = getHostRequirement(module);
                     Module target = module;
 
                     do
@@ -301,14 +298,14 @@
 
     private static List<Module> getResolvedSingletons(ResolverState state)
     {
-        Requirement req = new RequirementImpl(
+        BundleRequirementImpl req = new BundleRequirementImpl(
             null,
-            Capability.SINGLETON_NAMESPACE,
-            Collections.EMPTY_LIST,
-            Collections.EMPTY_LIST);
-        SortedSet<Capability> caps = state.getCandidates(req, true);
+            BundleCapabilityImpl.SINGLETON_NAMESPACE,
+            Collections.EMPTY_MAP,
+            Collections.EMPTY_MAP);
+        SortedSet<BundleCapabilityImpl> caps = state.getCandidates(req, true);
         List<Module> singletons = new ArrayList();
-        for (Capability cap : caps)
+        for (BundleCapabilityImpl cap : caps)
         {
             if (cap.getModule().isResolved())
             {
@@ -318,11 +315,11 @@
         return singletons;
     }
 
-    private static Capability getHostCapability(Module m)
+    private static BundleCapabilityImpl getHostCapability(Module m)
     {
-        for (Capability c : m.getCapabilities())
+        for (BundleCapabilityImpl c : m.getCapabilities())
         {
-            if (c.getNamespace().equals(Capability.HOST_NAMESPACE))
+            if (c.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
             {
                 return c;
             }
@@ -330,11 +327,11 @@
         return null;
     }
 
-    private static Requirement getHostRequirement(Module m)
+    private static BundleRequirementImpl getHostRequirement(Module m)
     {
-        for (Requirement r : m.getRequirements())
+        for (BundleRequirementImpl r : m.getRequirements())
         {
-            if (r.getNamespace().equals(Capability.HOST_NAMESPACE))
+            if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
             {
                 return r;
             }
@@ -354,7 +351,7 @@
 
         // If the module doesn't have dynamic imports, then just return
         // immediately.
-        List<Requirement> dynamics = module.getDynamicRequirements();
+        List<BundleRequirementImpl> dynamics = module.getDynamicRequirements();
         if ((dynamics == null) || dynamics.isEmpty())
         {
             return null;
@@ -362,11 +359,11 @@
 
         // If any of the module exports this package, then we cannot
         // attempt to dynamically import it.
-        List<Capability> caps = module.getCapabilities();
+        List<BundleCapabilityImpl> caps = module.getCapabilities();
         for (int i = 0; (caps != null) && (i < caps.size()); i++)
         {
-            if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                && caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+            if (caps.get(i).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                && caps.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
             {
                 return null;
             }
@@ -385,23 +382,23 @@
         // 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.
-        List<Directive> dirs = Collections.EMPTY_LIST;
-        List<Attribute> attrs = new ArrayList(1);
-        attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
-        Requirement req = new RequirementImpl(
-            module, Capability.PACKAGE_NAMESPACE, dirs, attrs);
-        SortedSet<Capability> candidates = state.getCandidates(req, false);
+        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);
+        SortedSet<BundleCapabilityImpl> candidates = state.getCandidates(req, false);
 
         // First find a dynamic requirement that matches the capabilities.
-        Requirement dynReq = null;
+        BundleRequirementImpl dynReq = null;
         for (int dynIdx = 0;
             (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
             dynIdx++)
         {
-            for (Iterator<Capability> itCand = candidates.iterator();
+            for (Iterator<BundleCapabilityImpl> itCand = candidates.iterator();
                 (dynReq == null) && itCand.hasNext(); )
             {
-                Capability cap = itCand.next();
+                BundleCapabilityImpl cap = itCand.next();
                 if (CapabilitySet.matches(cap, dynamics.get(dynIdx).getFilter()))
                 {
                     dynReq = dynamics.get(dynIdx);
@@ -413,9 +410,9 @@
         // any candidates that do not match it.
         if (dynReq != null)
         {
-            for (Iterator<Capability> itCand = candidates.iterator(); itCand.hasNext(); )
+            for (Iterator<BundleCapabilityImpl> itCand = candidates.iterator(); itCand.hasNext(); )
             {
-                Capability cap = itCand.next();
+                BundleCapabilityImpl cap = itCand.next();
                 if (!CapabilitySet.matches(cap, dynReq.getFilter()))
                 {
                     itCand.remove();
@@ -441,7 +438,7 @@
         Module module,
         Candidates allCandidates,
         Map<Module, Packages> modulePkgMap,
-        Map<Capability, List<Module>> usesCycleMap,
+        Map<BundleCapabilityImpl, List<Module>> usesCycleMap,
         Set<Module> cycle)
     {
         if (cycle.contains(module))
@@ -452,8 +449,8 @@
 
         // Create parallel arrays for requirement and proposed candidate
         // capability or actual capability if module is resolved or not.
-        List<Requirement> reqs = new ArrayList();
-        List<Capability> caps = new ArrayList();
+        List<BundleRequirementImpl> reqs = new ArrayList();
+        List<BundleCapabilityImpl> caps = new ArrayList();
         boolean isDynamicImport = false;
         if (module.isResolved())
         {
@@ -463,7 +460,7 @@
                 // Wrap the requirement as a hosted requirement
                 // if it comes from a fragment, since we will need
                 // to know the host.
-                Requirement r = wire.getRequirement();
+                BundleRequirementImpl r = wire.getRequirement();
                 if (!r.getModule().equals(wire.getImporter()))
                 {
                     r = new HostedRequirement(wire.getImporter(), r);
@@ -471,7 +468,7 @@
                 // Wrap the capability as a hosted capability
                 // if it comes from a fragment, since we will need
                 // to know the host.
-                Capability c = wire.getCapability();
+                BundleCapabilityImpl c = wire.getCapability();
                 if (!c.getModule().equals(wire.getExporter()))
                 {
                     c = new HostedCapability(wire.getExporter(), c);
@@ -483,17 +480,17 @@
             // 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 (Requirement req : module.getDynamicRequirements())
+            for (BundleRequirementImpl req : module.getDynamicRequirements())
             {
                 // Get the candidates for the current requirement.
-                SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
+                SortedSet<BundleCapabilityImpl> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
                     continue;
                 }
 
-                Capability cap = candCaps.iterator().next();
+                BundleCapabilityImpl cap = candCaps.iterator().next();
                 reqs.add(req);
                 caps.add(cap);
                 isDynamicImport = true;
@@ -504,17 +501,17 @@
         }
         else
         {
-            for (Requirement req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getRequirements())
             {
                 // Get the candidates for the current requirement.
-                SortedSet<Capability> candCaps = allCandidates.getCandidates(req);
+                SortedSet<BundleCapabilityImpl> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
                     continue;
                 }
 
-                Capability cap = candCaps.iterator().next();
+                BundleCapabilityImpl cap = candCaps.iterator().next();
                 reqs.add(req);
                 caps.add(cap);
             }
@@ -527,8 +524,8 @@
         // Second, add all imported packages to the target module's package space.
         for (int i = 0; i < reqs.size(); i++)
         {
-            Requirement req = reqs.get(i);
-            Capability cap = caps.get(i);
+            BundleRequirementImpl req = reqs.get(i);
+            BundleCapabilityImpl cap = caps.get(i);
             calculateExportedPackages(cap.getModule(), allCandidates, modulePkgMap);
             mergeCandidatePackages(module, req, cap, modulePkgMap, allCandidates);
         }
@@ -559,7 +556,7 @@
                     // Ignore modules that import from themselves.
                     if (!blame.m_cap.getModule().equals(module))
                     {
-                        List<Requirement> blameReqs = new ArrayList();
+                        List<BundleRequirementImpl> blameReqs = new ArrayList();
                         blameReqs.add(blame.m_reqs.get(0));
 
                         mergeUses(
@@ -577,7 +574,7 @@
             {
                 for (Blame blame : entry.getValue())
                 {
-                    List<Requirement> blameReqs = new ArrayList();
+                    List<BundleRequirementImpl> blameReqs = new ArrayList();
                     blameReqs.add(blame.m_reqs.get(0));
 
                     mergeUses(
@@ -594,16 +591,16 @@
     }
 
     private void mergeCandidatePackages(
-        Module current, Requirement currentReq, Capability candCap,
+        Module current, BundleRequirementImpl currentReq, BundleCapabilityImpl candCap,
         Map<Module, Packages> modulePkgMap,
         Candidates allCandidates)
     {
-        if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (candCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
             mergeCandidatePackage(
                 current, false, currentReq, candCap, modulePkgMap);
         }
-        else if (candCap.getNamespace().equals(Capability.MODULE_NAMESPACE))
+        else if (candCap.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
         {
 // TODO: FELIX3 - THIS NEXT LINE IS A HACK. IMPROVE HOW/WHEN WE CALCULATE EXPORTS.
             calculateExportedPackages(
@@ -627,12 +624,12 @@
 
             // If the candidate requires any other bundles with reexport visibility,
             // then we also need to merge their packages too.
-            for (Requirement req : candCap.getModule().getRequirements())
+            for (BundleRequirementImpl req : candCap.getModule().getRequirements())
             {
-                if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+                if (req.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
                 {
-                    Directive dir = req.getDirective(Constants.VISIBILITY_DIRECTIVE);
-                    if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT)
+                    String value = req.getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                    if ((value != null) && value.equals(Constants.VISIBILITY_REEXPORT)
                         && (allCandidates.getCandidates(req) != null))
                     {
                         mergeCandidatePackages(
@@ -649,13 +646,13 @@
 
     private void mergeCandidatePackage(
         Module current, boolean requires,
-        Requirement currentReq, Capability candCap,
+        BundleRequirementImpl currentReq, BundleCapabilityImpl candCap,
         Map<Module, Packages> modulePkgMap)
     {
-        if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (candCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
             String pkgName = (String)
-                candCap.getAttribute(Capability.PACKAGE_ATTR).getValue();
+                candCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
 
             // Since this capability represents a package, it will become
             // a hard constraint on the module's package space, so we need
@@ -699,12 +696,12 @@
 
     private void mergeUses(
         Module current, Packages currentPkgs,
-        Capability mergeCap, List<Requirement> blameReqs,
+        BundleCapabilityImpl mergeCap, List<BundleRequirementImpl> blameReqs,
         Map<Module, Packages> modulePkgMap,
         Candidates allCandidates,
-        Map<Capability, List<Module>> cycleMap)
+        Map<BundleCapabilityImpl, List<Module>> cycleMap)
     {
-        if (!mergeCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (!mergeCap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
             return;
         }
@@ -726,7 +723,7 @@
         list.add(current);
         cycleMap.put(mergeCap, list);
 
-        for (Capability candSourceCap : getPackageSources(mergeCap, modulePkgMap))
+        for (BundleCapabilityImpl candSourceCap : getPackageSources(mergeCap, modulePkgMap))
         {
             for (String usedPkgName : candSourceCap.getUses())
             {
@@ -758,7 +755,7 @@
                 {
                     if (blame.m_reqs != null)
                     {
-                        List<Requirement> blameReqs2 = new ArrayList(blameReqs);
+                        List<BundleRequirementImpl> blameReqs2 = new ArrayList(blameReqs);
                         blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
                         usedCaps.add(new Blame(blame.m_cap, blameReqs2));
                         mergeUses(current, currentPkgs, blame.m_cap, blameReqs2,
@@ -795,7 +792,7 @@
 
         ResolveException rethrow = null;
         Candidates permutation = null;
-        Set<Requirement> mutated = null;
+        Set<BundleRequirementImpl> mutated = null;
 
         // Check for conflicting imports from fragments.
         for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
@@ -884,7 +881,7 @@
 
                     for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
                     {
-                        Requirement req = usedBlame.m_reqs.get(reqIdx);
+                        BundleRequirementImpl req = usedBlame.m_reqs.get(reqIdx);
 
                         // If we've already permutated this requirement in another
                         // uses constraint, don't permutate it again just continue
@@ -897,7 +894,8 @@
                         // See if we can permutate the candidates for blamed
                         // requirement; there may be no candidates if the module
                         // associated with the requirement is already resolved.
-                        SortedSet<Capability> candidates = permutation.getCandidates(req);
+                        SortedSet<BundleCapabilityImpl> candidates =
+                            permutation.getCandidates(req);
                         if ((candidates != null) && (candidates.size() > 1))
                         {
                             mutated.add(req);
@@ -972,7 +970,7 @@
 
                         for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
                         {
-                            Requirement req = usedBlame.m_reqs.get(reqIdx);
+                            BundleRequirementImpl req = usedBlame.m_reqs.get(reqIdx);
 
                             // If we've already permutated this requirement in another
                             // uses constraint, don't permutate it again just continue
@@ -985,7 +983,8 @@
                             // See if we can permutate the candidates for blamed
                             // requirement; there may be no candidates if the module
                             // associated with the requirement is already resolved.
-                            SortedSet<Capability> candidates = permutation.getCandidates(req);
+                            SortedSet<BundleCapabilityImpl> candidates =
+                                permutation.getCandidates(req);
                             if ((candidates != null) && (candidates.size() > 1))
                             {
                                 mutated.add(req);
@@ -1016,7 +1015,7 @@
                     // Try to permutate the candidate for the original
                     // import requirement; only permutate it if we haven't
                     // done so already.
-                    Requirement req = importBlame.m_reqs.get(0);
+                    BundleRequirementImpl req = importBlame.m_reqs.get(0);
                     if (!mutated.contains(req))
                     {
                         // Since there may be lots of uses constraint violations
@@ -1063,7 +1062,7 @@
                         // to backtrack on our current candidate selection.
                         if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
                         {
-                            Requirement req = importBlame.m_reqs.get(0);
+                            BundleRequirementImpl req = importBlame.m_reqs.get(0);
                             permutate(allCandidates, req, m_importPermutations);
                         }
                         throw ex;
@@ -1074,9 +1073,9 @@
     }
 
     private static void permutate(
-        Candidates allCandidates, Requirement req, List<Candidates> permutations)
+        Candidates allCandidates, BundleRequirementImpl req, List<Candidates> permutations)
     {
-        SortedSet<Capability> candidates = allCandidates.getCandidates(req);
+        SortedSet<BundleCapabilityImpl> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             Candidates perm = allCandidates.copy();
@@ -1089,9 +1088,9 @@
     }
 
     private static void permutateIfNeeded(
-        Candidates allCandidates, Requirement req, List<Candidates> permutations)
+        Candidates allCandidates, BundleRequirementImpl req, List<Candidates> permutations)
     {
-        SortedSet<Capability> candidates = allCandidates.getCandidates(req);
+        SortedSet<BundleCapabilityImpl> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             // Check existing permutations to make sure we haven't
@@ -1103,7 +1102,7 @@
             boolean permutated = false;
             for (Candidates existingPerm : permutations)
             {
-                Set<Capability> existingPermCands = existingPerm.getCandidates(req);
+                Set<BundleCapabilityImpl> existingPermCands = existingPerm.getCandidates(req);
                 if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
                 {
                     permutated = true;
@@ -1131,14 +1130,14 @@
         packages = new Packages(module);
 
         // Get all exported packages.
-        Map<String, Capability> exports =
-            new HashMap<String, Capability>(module.getCapabilities().size());
-        for (Capability cap : module.getCapabilities())
+        Map<String, BundleCapabilityImpl> exports =
+            new HashMap<String, BundleCapabilityImpl>(module.getCapabilities().size());
+        for (BundleCapabilityImpl cap : module.getCapabilities())
         {
-            if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+            if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
             {
                 exports.put(
-                    (String) cap.getAttribute(Capability.PACKAGE_ATTR).getValue(),
+                    (String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
                     cap);
             }
         }
@@ -1150,32 +1149,32 @@
         {
             for (Wire wire : module.getWires())
             {
-                if (wire.getRequirement().getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (wire.getRequirement().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     String pkgName = (String) wire.getCapability()
-                        .getAttribute(Capability.PACKAGE_ATTR).getValue();
+                        .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
                     exports.remove(pkgName);
                 }
             }
         }
         else
         {
-            for (Requirement req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getRequirements())
             {
-                if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
-                    Set<Capability> cands = allCandidates.getCandidates(req);
+                    Set<BundleCapabilityImpl> cands = allCandidates.getCandidates(req);
                     if ((cands != null) && !cands.isEmpty())
                     {
                         String pkgName = (String) cands.iterator().next()
-                            .getAttribute(Capability.PACKAGE_ATTR).getValue();
+                            .getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR);
                         exports.remove(pkgName);
                     }
                 }
             }
         }
         // Add all non-substituted exports to the module's package space.
-        for (Entry<String, Capability> entry : exports.entrySet())
+        for (Entry<String, BundleCapabilityImpl> entry : exports.entrySet())
         {
             packages.m_exportedPkgs.put(
                 entry.getKey(), new Blame(entry.getValue(), null));
@@ -1185,7 +1184,8 @@
     }
 
     private boolean isCompatible(
-        Capability currentCap, Capability candCap, Map<Module, Packages> modulePkgMap)
+        BundleCapabilityImpl currentCap, BundleCapabilityImpl candCap,
+        Map<Module, Packages> modulePkgMap)
     {
         if ((currentCap != null) && (candCap != null))
         {
@@ -1194,28 +1194,30 @@
                 return true;
             }
 
-            List<Capability> currentSources =
+            List<BundleCapabilityImpl> currentSources =
                 getPackageSources(
                     currentCap,
                     modulePkgMap);
-            List<Capability> candSources =
+            List<BundleCapabilityImpl> candSources =
                 getPackageSources(
                     candCap,
                     modulePkgMap);
 
-            return currentSources.containsAll(candSources) || candSources.containsAll(currentSources);
+            return currentSources.containsAll(candSources)
+                || candSources.containsAll(currentSources);
         }
         return true;
     }
 
-    private Map<Capability, List<Capability>> m_packageSourcesCache = new HashMap();
+    private Map<BundleCapabilityImpl, List<BundleCapabilityImpl>> m_packageSourcesCache
+        = new HashMap();
 
-    private List<Capability> getPackageSources(
-        Capability cap, Map<Module, Packages> modulePkgMap)
+    private List<BundleCapabilityImpl> getPackageSources(
+        BundleCapabilityImpl cap, Map<Module, Packages> modulePkgMap)
     {
-        if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
-            List<Capability> sources = m_packageSourcesCache.get(cap);
+            List<BundleCapabilityImpl> sources = m_packageSourcesCache.get(cap);
             if (sources == null)
             {
                 sources = getPackageSourcesInternal(
@@ -1228,11 +1230,11 @@
         return Collections.EMPTY_LIST;
     }
 
-    private static List<Capability> getPackageSourcesInternal(
-        Capability cap, Map<Module, Packages> modulePkgMap, List<Capability> sources,
-        Set<Capability> cycleMap)
+    private static List<BundleCapabilityImpl> getPackageSourcesInternal(
+        BundleCapabilityImpl cap, Map<Module, Packages> modulePkgMap,
+        List<BundleCapabilityImpl> sources, Set<BundleCapabilityImpl> cycleMap)
     {
-        if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+        if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
         {
             if (cycleMap.contains(cap))
             {
@@ -1241,15 +1243,16 @@
             cycleMap.add(cap);
 
             // Get the package name associated with the capability.
-            String pkgName = cap.getAttribute(Capability.PACKAGE_ATTR).getValue().toString();
+            String pkgName = cap.getAttributes()
+                .get(BundleCapabilityImpl.PACKAGE_ATTR).toString();
 
             // Since a module can export the same package more than once, get
             // all package capabilities for the specified package name.
-            List<Capability> caps = cap.getModule().getCapabilities();
+            List<BundleCapabilityImpl> caps = cap.getModule().getCapabilities();
             for (int capIdx = 0; capIdx < caps.size(); capIdx++)
             {
-                if (caps.get(capIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
-                    && caps.get(capIdx).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+                if (caps.get(capIdx).getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
+                    && caps.get(capIdx).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
                 {
                     sources.add(caps.get(capIdx));
                 }
@@ -1279,7 +1282,7 @@
         return m;
     }
 
-    private static Capability getActualCapability(Capability c)
+    private static BundleCapabilityImpl getActualCapability(BundleCapabilityImpl c)
     {
         if (c instanceof HostedCapability)
         {
@@ -1288,7 +1291,7 @@
         return c;
     }
 
-    private static Requirement getActualRequirement(Requirement r)
+    private static BundleRequirementImpl getActualRequirement(BundleRequirementImpl r)
     {
         if (r instanceof HostedRequirement)
         {
@@ -1310,19 +1313,19 @@
             List<Wire> packageWires = new ArrayList<Wire>();
             List<Wire> moduleWires = new ArrayList<Wire>();
 
-            for (Requirement req : module.getRequirements())
+            for (BundleRequirementImpl req : module.getRequirements())
             {
-                SortedSet<Capability> cands = allCandidates.getCandidates(req);
+                SortedSet<BundleCapabilityImpl> cands = allCandidates.getCandidates(req);
                 if ((cands != null) && (cands.size() > 0))
                 {
-                    Capability cand = cands.iterator().next();
+                    BundleCapabilityImpl cand = cands.iterator().next();
                     if (!cand.getModule().isResolved())
                     {
                         populateWireMap(cand.getModule(),
                             modulePkgMap, wireMap, allCandidates);
                     }
                     // Ignore modules that import themselves.
-                    if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+                    if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE)
                         && !module.equals(cand.getModule()))
                     {
                         packageWires.add(
@@ -1332,7 +1335,7 @@
                                 getActualModule(cand.getModule()),
                                 getActualCapability(cand)));
                     }
-                    else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+                    else if (req.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
                     {
                         Packages candPkgs = modulePkgMap.get(cand.getModule());
                         moduleWires.add(
@@ -1390,8 +1393,7 @@
             {
                 // Ignore modules that import themselves.
                 if (!module.equals(blame.m_cap.getModule())
-                    && blame.m_cap.getAttribute(
-                        Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+                    && blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
                 {
                     if (!blame.m_cap.getModule().isResolved())
                     {
@@ -1399,18 +1401,18 @@
                             allCandidates);
                     }
 
-                    List<Attribute> attrs = new ArrayList();
-                    attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
+                    Map<String, Object> attrs = new HashMap(1);
+                    attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
                     packageWires.add(
                         new WireImpl(
                             module,
                             // We need an unique requirement here or else subsequent
                             // dynamic imports for the same dynamic requirement will
                             // conflict with previous ones.
-                            new RequirementImpl(
+                            new BundleRequirementImpl(
                                 module,
-                                Capability.PACKAGE_NAMESPACE,
-                                new ArrayList(0),
+                                BundleCapabilityImpl.PACKAGE_NAMESPACE,
+                                Collections.EMPTY_MAP,
                                 attrs),
                             getActualModule(blame.m_cap.getModule()),
                             getActualCapability(blame.m_cap)));
@@ -1464,13 +1466,13 @@
         {
             for (int i = 0; i < blame.m_reqs.size(); i++)
             {
-                Requirement req = blame.m_reqs.get(i);
+                BundleRequirementImpl req = blame.m_reqs.get(i);
                 sb.append("  ");
                 sb.append(req.getModule().getSymbolicName());
                 sb.append(" [");
                 sb.append(req.getModule().toString());
                 sb.append("]\n");
-                if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     sb.append("    import: ");
                 }
@@ -1480,7 +1482,7 @@
                 }
                 sb.append(req.getFilter().toString());
                 sb.append("\n     |");
-                if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (req.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     sb.append("\n    export: ");
                 }
@@ -1490,13 +1492,15 @@
                 }
                 if ((i + 1) < blame.m_reqs.size())
                 {
-                    Capability cap = Util.getSatisfyingCapability(
+                    BundleCapabilityImpl cap = Util.getSatisfyingCapability(
                         blame.m_reqs.get(i + 1).getModule(),
                         blame.m_reqs.get(i));
-                    if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                    if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                     {
-                        sb.append(cap.getAttribute(Capability.PACKAGE_ATTR).toString());
-                        Capability usedCap;
+                        sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
+                        sb.append("=");
+                        sb.append(cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
+                        BundleCapabilityImpl usedCap;
                         if ((i + 2) < blame.m_reqs.size())
                         {
                             usedCap = Util.getSatisfyingCapability(
@@ -1510,7 +1514,7 @@
                                 blame.m_reqs.get(i + 1));
                         }
                         sb.append("; uses:=");
-                        sb.append(usedCap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+                        sb.append(usedCap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
                     }
                     else
                     {
@@ -1520,17 +1524,21 @@
                 }
                 else
                 {
-                    Capability export = Util.getSatisfyingCapability(
+                    BundleCapabilityImpl export = Util.getSatisfyingCapability(
                         blame.m_cap.getModule(),
                         blame.m_reqs.get(i));
-                    sb.append(export.getAttribute(Capability.PACKAGE_ATTR).toString());
-                    if (!export.getAttribute(Capability.PACKAGE_ATTR).getValue()
-                        .equals(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue()))
+                    sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
+                    sb.append("=");
+                    sb.append(export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
+                    if (!export.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
+                        .equals(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)))
                     {
                         sb.append("; uses:=");
-                        sb.append(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+                        sb.append(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
                         sb.append("\n    export: ");
-                        sb.append(blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).toString());
+                        sb.append(BundleCapabilityImpl.PACKAGE_ATTR);
+                        sb.append("=");
+                        sb.append(blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).toString());
                     }
                     sb.append("\n  ");
                     sb.append(blame.m_cap.getModule().getSymbolicName());
@@ -1568,12 +1576,12 @@
             // 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 (Capability cap : m_module.getCapabilities())
+            for (BundleCapabilityImpl cap : m_module.getCapabilities())
             {
-                if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+                if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
                 {
                     pkgs.add((String)
-                        cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+                        cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
                 }
             }
             // Grab all required and reexported required packages.
@@ -1581,13 +1589,13 @@
             {
                 for (Blame blame : entry.getValue())
                 {
-                    Directive dir = blame.m_reqs.get(
-                        blame.m_reqs.size() - 1).getDirective(Constants.VISIBILITY_DIRECTIVE);
-                    if ((dir != null)
-                        && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
+                    String value = blame.m_reqs.get(
+                        blame.m_reqs.size() - 1).getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+                    if ((value != null)
+                        && value.equals(Constants.VISIBILITY_REEXPORT))
                     {
                         pkgs.add((String)
-                            blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+                            blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
                         break;
                     }
                 }
@@ -1598,24 +1606,26 @@
 
     private static class Blame
     {
-        public final Capability m_cap;
-        public final List<Requirement> m_reqs;
+        public final BundleCapabilityImpl m_cap;
+        public final List<BundleRequirementImpl> m_reqs;
 
-        public Blame(Capability cap, List<Requirement> reqs)
+        public Blame(BundleCapabilityImpl cap, List<BundleRequirementImpl> reqs)
         {
             m_cap = cap;
             m_reqs = reqs;
         }
 
+        @Override
         public String toString()
         {
             return m_cap.getModule()
-                + "." + m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue()
-                + (((m_reqs == null) || (m_reqs.size() == 0))
+                + "." + m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR)
+                + (((m_reqs == null) || m_reqs.isEmpty())
                     ? " NO BLAME"
                     : " BLAMED ON " + m_reqs);
         }
 
+        @Override
         public boolean equals(Object o)
         {
             return (o instanceof Blame) && m_reqs.equals(((Blame) o).m_reqs)
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
index c3b609c..a4a91df 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Wire.java
@@ -20,8 +20,8 @@
 
 import java.net.URL;
 import java.util.Enumeration;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 public interface Wire
 {
@@ -35,7 +35,7 @@
      * resulted in the creation of this wire.
      * @return
     **/
-    public Requirement getRequirement();
+    public BundleRequirementImpl getRequirement();
     /**
      * Returns the exporting module.
      * @return The exporting module.
@@ -46,7 +46,7 @@
      * satisfies the requirement of the importing module.
      * @return
     **/
-    public Capability getCapability();
+    public BundleCapabilityImpl getCapability();
     /**
      * Returns whether or not the wire has a given package name. For some
      * wires, such as ones for Require-Bundle, there may be many packages.
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
index 8e2358d..39ddf0f 100755
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireImpl.java
@@ -20,24 +20,24 @@
 
 import java.net.URL;
 import java.util.Enumeration;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.util.manifestparser.CapabilityImpl;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 class WireImpl implements Wire
 {
     private final Module m_importer;
-    private final Requirement m_req;
+    private final BundleRequirementImpl m_req;
     private final Module m_exporter;
-    private final Capability m_cap;
+    private final BundleCapabilityImpl m_cap;
 
-    public WireImpl(Module importer, Requirement ip, Module exporter, Capability ep)
+    public WireImpl(Module importer, BundleRequirementImpl ip,
+        Module exporter, BundleCapabilityImpl cap)
     {
         m_importer = importer;
         m_req = ip;
         m_exporter = exporter;
-        m_cap = ep;
+        m_cap = cap;
     }
 
     public Module getImporter()
@@ -45,7 +45,7 @@
         return m_importer;
     }
 
-    public Requirement getRequirement()
+    public BundleRequirementImpl getRequirement()
     {
         return m_req;
     }
@@ -55,7 +55,7 @@
         return m_exporter;
     }
 
-    public Capability getCapability()
+    public BundleCapabilityImpl getCapability()
     {
         return m_cap;
     }
@@ -73,8 +73,8 @@
      */
     public boolean hasPackage(String pkgName)
     {
-        return (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName));
+        return (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+            m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName));
     }
 
     /* (non-Javadoc)
@@ -89,15 +89,15 @@
 
         // Only check when the package of the target class is
         // the same as the package for the wire.
-        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        if (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+            m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
         {
             // Check the include/exclude filters from the target package
             // to make sure that the class is actually visible. We delegate
             // to the exporting module, rather than its content, so it can
             // it can follow any internal wires it may have (e.g., if the
             // package has multiple sources).
-            if (((CapabilityImpl) m_cap).isIncluded(name))
+            if (m_cap.isIncluded(name))
             {
                 clazz = m_exporter.getClassByDelegation(name);
             }
@@ -126,8 +126,8 @@
 
         // Only check when the package of the target resource is
         // the same as the package for the wire.
-        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        if (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+            m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
         {
             // Delegate to the exporting module, rather than its
             // content, so that it can follow any internal wires it may have
@@ -158,8 +158,8 @@
 
         // Only check when the package of the target resource is
         // the same as the package for the wire.
-        if (m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-            m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
+        if (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+            m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName))
         {
             urls = m_exporter.getResourcesByDelegation(name);
 
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
index a1bfc06..293c2b1 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/WireModuleImpl.java
@@ -21,25 +21,25 @@
 import java.net.URL;
 import java.util.Enumeration;
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 class WireModuleImpl implements Wire
 {
     private final Module m_importer;
-    private final Requirement m_req;
+    private final BundleRequirementImpl m_req;
     private final Module m_exporter;
-    private final Capability m_cap;
+    private final BundleCapabilityImpl m_cap;
     private final List<String> m_packages;
 
-    public WireModuleImpl(Module importer, Requirement requirement,
-        Module exporter, Capability capability, List<String> packages)
+    public WireModuleImpl(Module importer, BundleRequirementImpl requirement,
+        Module exporter, BundleCapabilityImpl cap, List<String> packages)
     {
         m_importer = importer;
         m_req = requirement;
         m_exporter = exporter;
-        m_cap = capability;
+        m_cap = cap;
         m_packages = packages;
     }
 
@@ -54,7 +54,7 @@
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getRequirement()
      */
-    public Requirement getRequirement()
+    public BundleRequirementImpl getRequirement()
     {
         return m_req;
     }
@@ -70,7 +70,7 @@
     /* (non-Javadoc)
      * @see org.apache.felix.framework.searchpolicy.IWire#getCapability()
      */
-    public Capability getCapability()
+    public BundleCapabilityImpl getCapability()
     {
         return m_cap;
     }
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 66437af..ab691c9 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
@@ -22,17 +22,16 @@
 import java.net.URL;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.capabilityset.Capability;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.resolver.Module;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.resolver.Wire;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
@@ -280,9 +279,9 @@
         return allow;
     }
 
-    public static Capability getSatisfyingCapability(Module m, Requirement req)
+    public static BundleCapabilityImpl getSatisfyingCapability(Module m, BundleRequirementImpl req)
     {
-        List<Capability> caps = m.getCapabilities();
+        List<BundleCapabilityImpl> caps = m.getCapabilities();
         for (int i = 0; (caps != null) && (i < caps.size()); i++)
         {
             if (caps.get(i).getNamespace().equals(req.getNamespace())
@@ -301,10 +300,10 @@
      * @param namespace capability namespace
      * @return array of matching capabilities or empty if none found
      */
-    public static List<Capability> getCapabilityByNamespace(Module module, String namespace)
+    public static List<BundleCapabilityImpl> getCapabilityByNamespace(Module module, String namespace)
     {
-        final List<Capability> matching = new ArrayList();
-        final List<Capability> caps = module.getCapabilities();
+        final List<BundleCapabilityImpl> matching = new ArrayList();
+        final List<BundleCapabilityImpl> caps = module.getCapabilities();
         for (int capIdx = 0; (caps != null) && (capIdx < caps.size()); capIdx++)
         {
             if (caps.get(capIdx).getNamespace().equals(namespace))
@@ -320,8 +319,8 @@
         List<Wire> wires = m.getWires();
         for (int i = 0; (wires != null) && (i < wires.size()); i++)
         {
-            if (wires.get(i).getCapability().getNamespace().equals(Capability.PACKAGE_NAMESPACE) &&
-                wires.get(i).getCapability().getAttribute(Capability.PACKAGE_ATTR).getValue().equals(name))
+            if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+                wires.get(i).getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
             {
                 return wires.get(i);
             }
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java
deleted file mode 100644
index 7944c95..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/CapabilityImpl.java
+++ /dev/null
@@ -1,230 +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.util.manifestparser;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.StringTokenizer;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.resolver.Module;
-import org.apache.felix.framework.util.Util;
-import org.osgi.framework.Constants;
-
-public class CapabilityImpl implements Capability
-{
-    private final Module m_module;
-    private final String m_namespace;
-    private final List<Directive> m_dirs;
-    private final List<Directive> m_dirsConst;
-    private final List<Attribute> m_attrs;
-    private final List<Attribute> m_attrsConst;
-    private final List<String> m_uses;
-    private final List<List<String>> m_includeFilter;
-    private final List<List<String>> m_excludeFilter;
-
-    public CapabilityImpl(Module module, String namespace,
-        List<Directive> dirs, List<Attribute> attrs)
-    {
-        m_namespace = namespace;
-        m_module = module;
-        m_dirs = dirs;
-        m_dirsConst = Collections.unmodifiableList(m_dirs);
-        m_attrs = attrs;
-        m_attrsConst = Collections.unmodifiableList(m_attrs);
-
-        // Find all export directives: uses, mandatory, include, and exclude.
-        String mandatory = "";
-        List<String> uses = new ArrayList(0);
-        List<List<String>> includeFilter = null, excludeFilter = null;
-        for (int dirIdx = 0; dirIdx < m_dirs.size(); dirIdx++)
-        {
-            if (m_dirs.get(dirIdx).getName().equals(Constants.USES_DIRECTIVE))
-            {
-                // Parse these uses directive.
-                StringTokenizer tok = new StringTokenizer(
-                    (String) m_dirs.get(dirIdx).getValue(), ",");
-                uses = new ArrayList<String>(tok.countTokens());
-                while (tok.hasMoreTokens())
-                {
-                    uses.add(tok.nextToken().trim());
-                }
-            }
-            else if (m_dirs.get(dirIdx).getName().equals(Constants.MANDATORY_DIRECTIVE))
-            {
-                mandatory = (String) m_dirs.get(dirIdx).getValue();
-            }
-            else if (m_dirs.get(dirIdx).getName().equals(Constants.INCLUDE_DIRECTIVE)
-                || m_dirs.get(dirIdx).getName().equals(Constants.EXCLUDE_DIRECTIVE))
-            {
-                List<List<String>> filterList = null;
-
-                List<String> filters = ManifestParser.parseDelimitedString(
-                    (String) m_dirs.get(dirIdx).getValue(), ",");
-                filterList = new ArrayList<List<String>>(filters.size());
-
-                for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
-                {
-                    List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
-                    filterList.add(substrings);
-                }
-
-                if (m_dirs.get(dirIdx).getName().equals(Constants.INCLUDE_DIRECTIVE))
-                {
-                    includeFilter = filterList;
-                }
-                else
-                {
-                    excludeFilter = filterList;
-                }
-            }
-        }
-
-        // 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, ", ");
-        while (tok.hasMoreTokens())
-        {
-            // Get attribute name.
-            String attrName = tok.nextToken().trim();
-            // Find attribute and mark it as mandatory.
-            boolean found = false;
-            for (int i = 0; (!found) && (i < m_attrs.size()); i++)
-            {
-                if (m_attrs.get(i).getName().equals(attrName))
-                {
-                    m_attrs.set(i, new Attribute(
-                        m_attrs.get(i).getName(),
-                        m_attrs.get(i).getValue(), true));
-                    found = true;
-                }
-            }
-            // If a specified mandatory attribute was not found,
-            // then error.
-            if (!found)
-            {
-                throw new IllegalArgumentException(
-                    "Mandatory attribute '" + attrName + "' does not exist.");
-            }
-        }
-    }
-
-    public Module getModule()
-    {
-        return m_module;
-    }
-
-    public String getNamespace()
-    {
-        return m_namespace;
-    }
-
-    public Directive getDirective(String name)
-    {
-        for (int i = 0; i < m_dirs.size(); i++)
-        {
-            if (m_dirs.get(i).getName().equals(name))
-            {
-                return m_dirs.get(i);
-            }
-        }
-        return null;
-    }
-
-    public List<Directive> getDirectives()
-    {
-        return m_dirsConst;
-    }
-
-    public Attribute getAttribute(String name)
-    {
-        for (int i = 0; i < m_attrs.size(); i++)
-        {
-            if (m_attrs.get(i).getName().equals(name))
-            {
-                return m_attrs.get(i);
-            }
-        }
-        return null;
-    }
-
-    public List<Attribute> getAttributes()
-    {
-        return m_attrsConst;
-    }
-
-    public List<String> getUses()
-    {
-        return m_uses;
-    }
-
-    public boolean isIncluded(String name)
-    {
-        if ((m_includeFilter == null) && (m_excludeFilter == null))
-        {
-            return true;
-        }
-
-        // Get the class name portion of the target class.
-        String className = Util.getClassName(name);
-
-        // If there are no include filters then all classes are included
-        // by default, otherwise try to find one match.
-        boolean included = (m_includeFilter == null);
-        for (int i = 0;
-            (!included) && (m_includeFilter != null) && (i < m_includeFilter.size());
-            i++)
-        {
-            included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
-        }
-
-        // If there are no exclude filters then no classes are excluded
-        // by default, otherwise try to find one match.
-        boolean excluded = false;
-        for (int i = 0;
-            (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size());
-            i++)
-        {
-            excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
-        }
-        return included && !excluded;
-    }
-
-    public String toString()
-    {
-        if (m_module == null)
-        {
-            return m_attrs.toString();
-        }
-        if (m_namespace.equals(Capability.PACKAGE_NAMESPACE))
-        {
-            return "[" + m_module + "] "
-                + m_namespace + "; " + getAttribute(Capability.PACKAGE_ATTR);
-        }
-        return "[" + m_module + "] " + m_namespace + "; " + m_attrs;
-    }
-}
\ No newline at end of file
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 3ca16aa..fed65bf 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
@@ -23,13 +23,11 @@
 import java.util.Map.Entry;
 
 import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.capabilityset.Capability;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Directive;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.resolver.Module;
-import org.apache.felix.framework.capabilityset.Requirement;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.VersionRange;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.*;
 
 public class ManifestParser
@@ -43,9 +41,9 @@
     private volatile boolean m_isExtension = false;
     private volatile String m_bundleSymbolicName;
     private volatile Version m_bundleVersion;
-    private volatile List<Capability> m_capabilities;
-    private volatile List<Requirement> m_requirements;
-    private volatile List<Requirement> m_dynamicRequirements;
+    private volatile List<BundleCapabilityImpl> m_capabilities;
+    private volatile List<BundleRequirementImpl> m_requirements;
+    private volatile List<BundleRequirementImpl> m_dynamicRequirements;
     private volatile List<R4LibraryClause> m_libraryClauses;
     private volatile boolean m_libraryHeadersOptional = false;
 
@@ -65,7 +63,7 @@
         }
 
         // Create lists to hold capabilities and requirements.
-        List<Capability> capList = new ArrayList();
+        List<BundleCapabilityImpl> capList = new ArrayList();
 
         //
         // Parse bundle version.
@@ -76,7 +74,8 @@
         {
             try
             {
-                m_bundleVersion = Version.parseVersion((String) headerMap.get(Constants.BUNDLE_VERSION));
+                m_bundleVersion = Version.parseVersion(
+                    (String) headerMap.get(Constants.BUNDLE_VERSION));
             }
             catch (RuntimeException ex)
             {
@@ -93,11 +92,11 @@
         // Parse bundle symbolic name.
         //
 
-        Capability moduleCap = parseBundleSymbolicName(owner, m_headerMap);
+        BundleCapabilityImpl moduleCap = parseBundleSymbolicName(owner, m_headerMap);
         if (moduleCap != null)
         {
             m_bundleSymbolicName = (String)
-                moduleCap.getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE).getValue();
+                moduleCap.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
 
             // Add a module capability and a host capability to all
             // non-fragment bundles. A host capability is the same
@@ -108,9 +107,11 @@
             if (headerMap.get(Constants.FRAGMENT_HOST) == null)
             {
                 capList.add(moduleCap);
-                capList.add(new CapabilityImpl(
-                    owner, Capability.HOST_NAMESPACE, new ArrayList<Directive>(0),
-                    ((CapabilityImpl) moduleCap).getAttributes()));
+                capList.add(new BundleCapabilityImpl(
+                    owner, BundleCapabilityImpl.HOST_NAMESPACE,
+                    Collections.EMPTY_MAP,
+// TODO: OSGi R4.3 - Wraps map as unmodifiable twice.
+                    moduleCap.getAttributes()));
             }
 
             // Add a singleton capability if the bundle is a singleton.
@@ -121,9 +122,11 @@
             // can be singletons too.
             if (isSingleton(moduleCap))
             {
-                capList.add(new CapabilityImpl(
-                    owner, Capability.SINGLETON_NAMESPACE, new ArrayList<Directive>(0),
-                    ((CapabilityImpl) moduleCap).getAttributes()));
+                capList.add(new BundleCapabilityImpl(
+                    owner, BundleCapabilityImpl.SINGLETON_NAMESPACE,
+                    Collections.EMPTY_MAP,
+// TODO: OSGi R4.3 - Wraps map as unmodifiable twice.
+                    moduleCap.getAttributes()));
             }
         }
 
@@ -138,7 +141,7 @@
         // Parse Fragment-Host.
         //
 
-        List<Requirement> hostReqs = parseFragmentHost(m_logger, owner, m_headerMap);
+        List<BundleRequirementImpl> hostReqs = parseFragmentHost(m_logger, owner, m_headerMap);
 
         //
         // Parse Require-Bundle
@@ -147,7 +150,7 @@
         List<ParsedHeaderClause> requireClauses =
             parseStandardHeader((String) headerMap.get(Constants.REQUIRE_BUNDLE));
         requireClauses = normalizeRequireClauses(m_logger, requireClauses, getManifestVersion());
-        List<Requirement> requireReqs = convertRequires(requireClauses, owner);
+        List<BundleRequirementImpl> requireReqs = convertRequires(requireClauses, owner);
 
         //
         // Parse Import-Package.
@@ -156,7 +159,7 @@
         List<ParsedHeaderClause> importClauses =
             parseStandardHeader((String) headerMap.get(Constants.IMPORT_PACKAGE));
         importClauses = normalizeImportClauses(m_logger, importClauses, getManifestVersion());
-        List<Requirement> importReqs = convertImports(importClauses, owner);
+        List<BundleRequirementImpl> importReqs = convertImports(importClauses, owner);
 
         //
         // Parse DynamicImport-Package.
@@ -176,7 +179,7 @@
             parseStandardHeader((String) headerMap.get(Constants.EXPORT_PACKAGE));
         exportClauses = normalizeExportClauses(logger, exportClauses,
             getManifestVersion(), m_bundleSymbolicName, m_bundleVersion);
-        List<Capability> exportCaps = convertExports(exportClauses, owner);
+        List<BundleCapabilityImpl> exportCaps = convertExports(exportClauses, owner);
 
         //
         // Calculate implicit imports.
@@ -239,18 +242,14 @@
         m_isExtension = checkExtensionBundle(headerMap);
     }
 
-    private static boolean isSingleton(Capability cap)
+    private static boolean isSingleton(BundleCapabilityImpl cap)
     {
-        if (cap.getNamespace().equals(Capability.MODULE_NAMESPACE))
+        if (cap.getNamespace().equals(BundleCapabilityImpl.MODULE_NAMESPACE))
         {
-            final List<Directive> dirs = cap.getDirectives();
-            for (int dirIdx = 0; (dirs != null) && (dirIdx < dirs.size()); dirIdx++)
+            String value = cap.getDirectives().get(Constants.SINGLETON_DIRECTIVE);
+            if ((value != null) && Boolean.valueOf(value))
             {
-                if (dirs.get(dirIdx).getName().equalsIgnoreCase(Constants.SINGLETON_DIRECTIVE)
-                    && Boolean.valueOf((String) dirs.get(dirIdx).getValue()))
-                {
-                    return true;
-                }
+                return true;
             }
         }
         return false;
@@ -262,27 +261,16 @@
     {
         // Verify that the values are equals if the package specifies
         // both version and specification-version attributes.
-        Map<String, Attribute> attrMap = new HashMap();
         for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
         {
-            // Put attributes for current clause in a map for easy lookup.
-            attrMap.clear();
-            for (int attrIdx = 0;
-                attrIdx < clauses.get(clauseIdx).m_attrs.size();
-                attrIdx++)
-            {
-                Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
-                attrMap.put(attr.getName(), attr);
-            }
-
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
-            Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
-                if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+                if (!((String) v).trim().equals(((String) sv).trim()))
                 {
                     throw new IllegalArgumentException(
                         "Both version and specification-version are specified, but they are not equal.");
@@ -293,29 +281,21 @@
             // it to the VersionRange type.
             if ((v != null) || (sv != null))
             {
-                attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                attrMap.put(Constants.VERSION_ATTRIBUTE,
-                    new Attribute(
-                        Constants.VERSION_ATTRIBUTE,
-                        VersionRange.parse(v.getValue().toString()),
-                        v.isMandatory()));
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.VERSION_ATTRIBUTE,
+                    VersionRange.parse(v.toString()));
             }
 
             // If bundle version is specified, then convert its type to VersionRange.
-            v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+            v = clauses.get(clauseIdx).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
             if (v != null)
             {
-                attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
-                    new Attribute(
-                        Constants.BUNDLE_VERSION_ATTRIBUTE,
-                        VersionRange.parse(v.getValue().toString()),
-                        v.isMandatory()));
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.BUNDLE_VERSION_ATTRIBUTE,
+                    VersionRange.parse(v.toString()));
             }
-
-            // Re-copy the attributes in case they changed.
-            clauses.get(clauseIdx).m_attrs.clear();
-            clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
         }
 
         // Verify java.* is not imported, nor any duplicate imports.
@@ -358,7 +338,7 @@
             for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
             {
                 // R3 bundles cannot have directives on their imports.
-                if (clauses.get(clauseIdx).m_dirs.size() != 0)
+                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
                 {
                     throw new BundleException("R3 imports cannot contain directives.");
                 }
@@ -368,33 +348,29 @@
                 // because the package class normalizes to "version" to avoid having
                 // future special cases. This could be changed if more strict behavior
                 // is required.
-                if (clauses.get(clauseIdx).m_attrs.size() != 0)
+                if (!clauses.get(clauseIdx).m_attrs.isEmpty())
                 {
                     // R3 package requirements should only have version attributes.
-                    Attribute pkgVersion =
-                        new Attribute(Capability.VERSION_ATTR,
-                            new VersionRange(Version.emptyVersion, true, null, true), false);
-                    for (int attrIdx = 0;
-                        attrIdx < clauses.get(clauseIdx).m_attrs.size();
-                        attrIdx++)
+                    Object pkgVersion = new VersionRange(Version.emptyVersion, true, null, true);
+                    for (Entry<String, Object> entry : clauses.get(clauseIdx).m_attrs.entrySet())
                     {
-                        if (clauses.get(clauseIdx).m_attrs.get(attrIdx)
-                          .getName().equals(Capability.VERSION_ATTR))
+                        if (entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
                         {
-                            pkgVersion = clauses.get(clauseIdx).m_attrs.get(attrIdx);
+                            pkgVersion = entry.getValue();
                         }
                         else
                         {
                             logger.log(Logger.LOG_WARNING,
                                 "Unknown R3 import attribute: "
-                                    + clauses.get(clauseIdx).m_attrs.get(attrIdx).getName());
+                                    + entry.getKey());
                         }
                     }
 
                     // Recreate the import to remove any other attributes
                     // and add version if missing.
-                    ArrayList<Attribute> attrs = new ArrayList<Attribute>(1);
-                    attrs.add(pkgVersion);
+                    Map<String, Object> attrs = new HashMap<String, Object>(1);
+                    attrs.put(
+                        BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
                     clauses.set(clauseIdx, new ParsedHeaderClause(
                         clauses.get(clauseIdx).m_paths,
                         clauses.get(clauseIdx).m_dirs,
@@ -406,7 +382,7 @@
         return clauses;
     }
 
-    private static List<Requirement> convertImports(
+    private static List<BundleRequirementImpl> convertImports(
         List<ParsedHeaderClause> clauses, Module owner)
     {
         // Now convert generic header clauses into requirements.
@@ -418,18 +394,23 @@
                 pathIdx++)
             {
                 // Prepend the package name to the array of attributes.
-                List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
-                List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
-                newAttrs.add(new Attribute(
-                    Capability.PACKAGE_ATTR,
-                    clauses.get(clauseIdx).m_paths.get(pathIdx), false));
-                newAttrs.addAll(attrs);
+                Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
+                // Note that we use a linked hash map here to ensure the
+                // package attribute is first, which will make indexing
+                // more efficient.
+// TODO: OSGi R4.3 - This is a hack...perhaps we should use the standard "key"
+//       notion where namespace is also the name of the key attribute.
+                Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
+                newAttrs.put(
+                    BundleCapabilityImpl.PACKAGE_ATTR,
+                    clauses.get(clauseIdx).m_paths.get(pathIdx));
+                newAttrs.putAll(attrs);
 
                 // Create package requirement and add to requirement list.
                 reqList.add(
-                    new RequirementImpl(
+                    new BundleRequirementImpl(
                         owner,
-                        Capability.PACKAGE_NAMESPACE,
+                        BundleCapabilityImpl.PACKAGE_NAMESPACE,
                         clauses.get(clauseIdx).m_dirs,
                         newAttrs));
             }
@@ -444,27 +425,16 @@
     {
         // Verify that the values are equals if the package specifies
         // both version and specification-version attributes.
-        Map<String, Attribute> attrMap = new HashMap();
         for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
         {
-            // Put attributes for current clause in a map for easy lookup.
-            attrMap.clear();
-            for (int attrIdx = 0;
-                attrIdx < clauses.get(clauseIdx).m_attrs.size();
-                attrIdx++)
-            {
-                Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
-                attrMap.put(attr.getName(), attr);
-            }
-
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
-            Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
-                if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+                if (!((String) v).trim().equals(((String) sv).trim()))
                 {
                     throw new IllegalArgumentException(
                         "Both version and specification-version are specified, but they are not equal.");
@@ -475,29 +445,21 @@
             // it to the VersionRange type.
             if ((v != null) || (sv != null))
             {
-                attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                attrMap.put(Constants.VERSION_ATTRIBUTE,
-                    new Attribute(
-                        Constants.VERSION_ATTRIBUTE,
-                        VersionRange.parse(v.getValue().toString()),
-                        v.isMandatory()));
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.VERSION_ATTRIBUTE,
+                    VersionRange.parse(v.toString()));
             }
 
             // If bundle version is specified, then convert its type to VersionRange.
-            v = attrMap.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+            v = clauses.get(clauseIdx).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
             if (v != null)
             {
-                attrMap.put(Constants.BUNDLE_VERSION_ATTRIBUTE,
-                    new Attribute(
-                        Constants.BUNDLE_VERSION_ATTRIBUTE,
-                        VersionRange.parse(v.getValue().toString()),
-                        v.isMandatory()));
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.BUNDLE_VERSION_ATTRIBUTE,
+                    VersionRange.parse(v.toString()));
             }
-
-            // Re-copy the attributes in case they changed.
-            clauses.get(clauseIdx).m_attrs.clear();
-            clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
         }
 
         // Dynamic imports can have duplicates, so just check for import
@@ -530,7 +492,7 @@
             for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
             {
                 // R3 bundles cannot have directives on their imports.
-                if (clauses.get(clauseIdx).m_dirs.size() != 0)
+                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
                 {
                     throw new BundleException("R3 imports cannot contain directives.");
                 }
@@ -568,27 +530,16 @@
 
         // If both version and specification-version attributes are specified,
         // then verify that the values are equal.
-        Map<String, Attribute> attrMap = new HashMap();
         for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
         {
-            // Put attributes for current clause in a map for easy lookup.
-            attrMap.clear();
-            for (int attrIdx = 0;
-                attrIdx < clauses.get(clauseIdx).m_attrs.size();
-                attrIdx++)
-            {
-                Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
-                attrMap.put(attr.getName(), attr);
-            }
-
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Attribute v = attrMap.get(Constants.VERSION_ATTRIBUTE);
-            Attribute sv = attrMap.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
-                if (!((String) v.getValue()).trim().equals(((String) sv.getValue()).trim()))
+                if (!((String) v).trim().equals(((String) sv).trim()))
                 {
                     throw new IllegalArgumentException(
                         "Both version and specification-version are specified, but they are not equal.");
@@ -598,8 +549,7 @@
             // Always add the default version if not specified.
             if ((v == null) && (sv == null))
             {
-                v = new Attribute(
-                    Constants.VERSION_ATTRIBUTE, Version.emptyVersion, false);
+                v = Version.emptyVersion;
             }
 
             // Ensure that only the "version" attribute is used and convert
@@ -607,17 +557,11 @@
             if ((v != null) || (sv != null))
             {
                 // Convert version attribute to type Version.
-                attrMap.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                attrMap.put(Constants.VERSION_ATTRIBUTE,
-                    new Attribute(
-                        Constants.VERSION_ATTRIBUTE,
-                        Version.parseVersion(v.getValue().toString()),
-                        v.isMandatory()));
-
-                // Re-copy the attributes since they have changed.
-                clauses.get(clauseIdx).m_attrs.clear();
-                clauses.get(clauseIdx).m_attrs.addAll(attrMap.values());
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.VERSION_ATTRIBUTE,
+                    Version.parseVersion(v.toString()));
             }
         }
 
@@ -627,26 +571,20 @@
         {
             for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
             {
-                // R3 package capabilities should only have a version attribute.
-                List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
-                for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+                // Find symbolic name and version attribute, if present.
+                if (clauses.get(clauseIdx).m_attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
+                    || clauses.get(clauseIdx).m_attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
                 {
-                    // Find symbolic name and version attribute, if present.
-                    if (attrs.get(attrIdx).getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE) ||
-                        attrs.get(attrIdx).getName().equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
-                    {
-                        throw new BundleException(
-                            "Exports must not specify bundle symbolic name or bundle version.");
-                    }
+                    throw new BundleException(
+                        "Exports must not specify bundle symbolic name or bundle version.");
                 }
 
                 // Now that we know that there are no bundle symbolic name and version
                 // attributes, add them since the spec says they are there implicitly.
-                attrs.add(new Attribute(
-                    Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn, false));
-                attrs.add(new Attribute(
-                    Constants.BUNDLE_VERSION_ATTRIBUTE, bv, false));
-                ((ArrayList) attrs).trimToSize();
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
+                clauses.get(clauseIdx).m_attrs.put(
+                    Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
             }
         }
         else if (!mv.equals("2"))
@@ -657,7 +595,7 @@
             for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
             {
                 // R3 bundles cannot have directives on their exports.
-                if (clauses.get(clauseIdx).m_dirs.size() != 0)
+                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
                 {
                     throw new BundleException("R3 exports cannot contain directives.");
                 }
@@ -667,30 +605,31 @@
                 // because the package class normalizes to "version" to avoid having
                 // future special cases. This could be changed if more strict behavior
                 // is required.
-                if (clauses.get(clauseIdx).m_attrs.size() != 0)
+                if (!clauses.get(clauseIdx).m_attrs.isEmpty())
                 {
                     // R3 package capabilities should only have a version attribute.
-                    List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
-                    Attribute pkgVersion = new Attribute(Capability.VERSION_ATTR, Version.emptyVersion, false);
-                    for (int attrIdx = 0; attrIdx < attrs.size(); attrIdx++)
+                    Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
+                    Object pkgVersion = clauses.get(clauseIdx).m_attrs
+                        .get(BundleCapabilityImpl.VERSION_ATTR);
+                    pkgVersion = (pkgVersion == null)
+                        ? Version.emptyVersion
+                        : pkgVersion;
+                    for (Entry<String, Object> entry : clauses.get(clauseIdx).m_attrs.entrySet())
                     {
-                        if (attrs.get(attrIdx).getName().equals(Capability.VERSION_ATTR))
-                        {
-                            pkgVersion = attrs.get(attrIdx);
-                        }
-                        else
+                        if (!entry.getKey().equals(
+                            BundleCapabilityImpl.VERSION_ATTR))
                         {
                             logger.log(
                                 Logger.LOG_WARNING,
                                 "Unknown R3 export attribute: "
-                                + attrs.get(attrIdx).getName());
+                                + entry.getKey());
                         }
                     }
 
                     // Recreate the export to remove any other attributes
                     // and add version if missing.
-                    List<Attribute> newAttrs = new ArrayList<Attribute>(2);
-                    newAttrs.add(pkgVersion);
+                    Map<String, Object> newAttrs = new HashMap<String, Object>(1);
+                    newAttrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
                     clauses.set(clauseIdx, new ParsedHeaderClause(
                         clauses.get(clauseIdx).m_paths,
                         clauses.get(clauseIdx).m_dirs,
@@ -743,17 +682,17 @@
         return m_bundleVersion;
     }
 
-    public List<Capability> getCapabilities()
+    public List<BundleCapabilityImpl> getCapabilities()
     {
         return m_capabilities;
     }
 
-    public List<Requirement> getRequirements()
+    public List<BundleRequirementImpl> getRequirements()
     {
         return m_requirements;
     }
 
-    public List<Requirement> getDynamicRequirements()
+    public List<BundleRequirementImpl> getDynamicRequirements()
     {
         return m_dynamicRequirements;
     }
@@ -853,7 +792,7 @@
 
             // Select the matching native clause.
             int selected = 0;
-            if (clauseList.size() == 0)
+            if (clauseList.isEmpty())
             {
                 // If optional clause exists, no error thrown.
                 if (m_libraryHeadersOptional)
@@ -936,7 +875,7 @@
             }
         }
 
-        if (selection.size() == 0)
+        if (selection.isEmpty())
         {
             // Re-init index list.
             selection.clear();
@@ -967,7 +906,7 @@
         }
 
         // Return the first sorted clause
-        if (selection.size() == 0)
+        if (selection.isEmpty())
         {
             return 0;
         }
@@ -978,7 +917,7 @@
     }
 
     private static List<ParsedHeaderClause> calculateImplicitImports(
-        List<Capability> exports, List<ParsedHeaderClause> imports)
+        List<BundleCapabilityImpl> exports, List<ParsedHeaderClause> imports)
         throws BundleException
     {
         List<ParsedHeaderClause> clauseList = new ArrayList();
@@ -1000,34 +939,32 @@
         // Add import requirement for each export capability.
         for (int i = 0; i < exports.size(); i++)
         {
-            if (map.get(exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue()) == null)
+            if (map.get(exports.get(i).getAttributes()
+                .get(BundleCapabilityImpl.PACKAGE_ATTR)) == null)
             {
                 // Convert Version to VersionRange.
-                List<Attribute> attrs = new ArrayList<Attribute>(exports.get(i).getAttributes());
-                for (int attrIdx = 0; (attrs != null) && (attrIdx < attrs.size()); attrIdx++)
+                Map<String, Object> attrs = new HashMap<String, Object>();
+                Object version = exports.get(i).getAttributes().get(Constants.VERSION_ATTRIBUTE);
+                if (version != null)
                 {
-                    if (attrs.get(attrIdx).getName().equals(Constants.VERSION_ATTRIBUTE))
-                    {
-                        attrs.set(attrIdx, new Attribute(
-                            attrs.get(attrIdx).getName(),
-                            VersionRange.parse(attrs.get(attrIdx).getValue().toString()),
-                            attrs.get(attrIdx).isMandatory()));
-                    }
+                    attrs.put(
+                        Constants.VERSION_ATTRIBUTE,
+                        VersionRange.parse(version.toString()));
                 }
 
                 List<String> paths = new ArrayList();
                 paths.add((String)
-                    exports.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue());
+                    exports.get(i).getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
                 clauseList.add(
-                    new ParsedHeaderClause(paths, new ArrayList<Directive>(0), attrs));
+                    new ParsedHeaderClause(paths, Collections.EMPTY_MAP, attrs));
             }
         }
 
         return clauseList;
     }
 
-    private static List<Capability> calculateImplicitUses(
-        List<Capability> exports, List<ParsedHeaderClause> imports)
+    private static List<BundleCapabilityImpl> calculateImplicitUses(
+        List<BundleCapabilityImpl> exports, List<ParsedHeaderClause> imports)
         throws BundleException
     {
         // Add a "uses" directive onto each export of R3 bundles
@@ -1045,16 +982,14 @@
                     + imports.get(i).m_paths.get(pathIdx);
             }
         }
-        Directive uses = new Directive(
-            Constants.USES_DIRECTIVE, usesValue);
         for (int i = 0; i < exports.size(); i++)
         {
-            List<Directive> dirList = new ArrayList<Directive>(1);
-            dirList.add(uses);
-            exports.set(i, new CapabilityImpl(
+            Map<String, String> dirs = new HashMap<String, String>(1);
+            dirs.put(Constants.USES_DIRECTIVE, usesValue);
+            exports.set(i, new BundleCapabilityImpl(
                 exports.get(i).getModule(),
-                Capability.PACKAGE_NAMESPACE,
-                dirList,
+                BundleCapabilityImpl.PACKAGE_NAMESPACE,
+                dirs,
                 exports.get(i).getAttributes()));
         }
 
@@ -1063,13 +998,13 @@
 
     private static boolean checkExtensionBundle(Map headerMap) throws BundleException
     {
-        Directive extension = parseExtensionBundleHeader(
+        Object extension = parseExtensionBundleHeader(
             (String) headerMap.get(Constants.FRAGMENT_HOST));
 
         if (extension != null)
         {
-            if (!(Constants.EXTENSION_FRAMEWORK.equals(extension.getValue()) ||
-                Constants.EXTENSION_BOOTCLASSPATH.equals(extension.getValue())))
+            if (!(Constants.EXTENSION_FRAMEWORK.equals(extension) ||
+                Constants.EXTENSION_BOOTCLASSPATH.equals(extension)))
             {
                 throw new BundleException(
                     "Extension bundle must have either 'extension:=framework' or 'extension:=bootclasspath'");
@@ -1087,7 +1022,7 @@
         return false;
     }
 
-    private static Capability parseBundleSymbolicName(Module owner, Map headerMap)
+    private static BundleCapabilityImpl parseBundleSymbolicName(Module owner, Map headerMap)
         throws BundleException
     {
         List<ParsedHeaderClause> clauses = parseStandardHeader(
@@ -1130,14 +1065,12 @@
 
             // Create a module capability and return it.
             String symName = (String) clauses.get(0).m_paths.get(0);
-            List<Attribute> attrs = new ArrayList<Attribute>(2);
-            attrs.add(new Attribute(
-                Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName, false));
-            attrs.add(new Attribute(
-                Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion, false));
-            return new CapabilityImpl(
+            Map<String, Object> attrs = new HashMap<String, Object>(2);
+            attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symName);
+            attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
+            return new BundleCapabilityImpl(
                 owner,
-                Capability.MODULE_NAMESPACE,
+                BundleCapabilityImpl.MODULE_NAMESPACE,
                 clauses.get(0).m_dirs,
                 attrs);
         }
@@ -1145,11 +1078,11 @@
         return null;
     }
 
-    private static List<Requirement> parseFragmentHost(
+    private static List<BundleRequirementImpl> parseFragmentHost(
         Logger logger, Module owner, Map headerMap)
         throws BundleException
     {
-        List<Requirement> reqs = new ArrayList();
+        List<BundleRequirementImpl> reqs = new ArrayList();
 
         String mv = getManifestVersion(headerMap);
         if ((mv != null) && mv.equals("2"))
@@ -1173,10 +1106,12 @@
                 }
 
                 // Strip all attributes other than bundle-version.
-                for (Iterator<Attribute> it = clauses.get(0).m_attrs.iterator(); it.hasNext(); )
+                for (Iterator<Entry<String, Object>> it =
+                        clauses.get(0).m_attrs.entrySet().iterator();
+                    it.hasNext(); )
                 {
-                    Attribute attr = it.next();
-                    if (!attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
+                    Entry<String, Object> entry = it.next();
+                    if (!entry.getKey().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
                     {
                         it.remove();
                     }
@@ -1184,26 +1119,24 @@
 
                 // If the bundle-version attribute is specified, then convert
                 // it to the proper type.
-                if (clauses.get(0).m_attrs.size() == 1)
+                Object value = clauses.get(0).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+                if (value != null)
                 {
-                    Attribute attr = clauses.get(0).m_attrs.get(0);
-                    clauses.get(0).m_attrs.set(0,
-                        new Attribute(
-                            Constants.BUNDLE_VERSION_ATTRIBUTE,
-                            VersionRange.parse(attr.getValue().toString()),
-                            attr.isMandatory()));
+                    clauses.get(0).m_attrs.put(
+                        Constants.BUNDLE_VERSION_ATTRIBUTE,
+                        VersionRange.parse(value.toString()));
                 }
 
                 // Prepend the host symbolic name to the array of attributes.
-                List<Attribute> attrs = clauses.get(0).m_attrs;
-                List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
-                newAttrs.add(new Attribute(
+                Map<String, Object> attrs = clauses.get(0).m_attrs;
+                Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
+                newAttrs.put(
                     Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
-                    clauses.get(0).m_paths.get(0), false));
-                newAttrs.addAll(attrs);
+                    clauses.get(0).m_paths.get(0));
+                newAttrs.putAll(attrs);
 
-                reqs.add(new RequirementImpl(
-                    owner, Capability.HOST_NAMESPACE,
+                reqs.add(new BundleRequirementImpl(
+                    owner, BundleCapabilityImpl.HOST_NAMESPACE,
                     clauses.get(0).m_dirs,
                     newAttrs));
             }
@@ -1222,11 +1155,11 @@
         return reqs;
     }
 
-    public static List<Capability> parseExportHeader(
+    public static List<BundleCapabilityImpl> parseExportHeader(
         Logger logger, Module owner, String header, String bsn, Version bv)
     {
 
-        List<Capability> caps = null;
+        List<BundleCapabilityImpl> caps = null;
         try
         {
             List<ParsedHeaderClause> exportClauses = parseStandardHeader(header);
@@ -1240,10 +1173,10 @@
         return caps;
     }
 
-    private static List<Capability> convertExports(
+    private static List<BundleCapabilityImpl> convertExports(
         List<ParsedHeaderClause> clauses, Module owner)
     {
-        List<Capability> capList = new ArrayList();
+        List<BundleCapabilityImpl> capList = new ArrayList();
         for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
         {
             for (int pathIdx = 0;
@@ -1251,18 +1184,18 @@
                 pathIdx++)
             {
                 // Prepend the package name to the array of attributes.
-                List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
-                List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
-                newAttrs.add(new Attribute(
-                    Capability.PACKAGE_ATTR,
-                    clauses.get(clauseIdx).m_paths.get(pathIdx), false));
-                newAttrs.addAll(attrs);
+                Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
+                Map<String, Object> newAttrs = new HashMap<String, Object>(attrs.size() + 1);
+                newAttrs.put(
+                    BundleCapabilityImpl.PACKAGE_ATTR,
+                    clauses.get(clauseIdx).m_paths.get(pathIdx));
+                newAttrs.putAll(attrs);
 
                 // Create package capability and add to capability list.
                 capList.add(
-                    new CapabilityImpl(
+                    new BundleCapabilityImpl(
                         owner,
-                        Capability.PACKAGE_NAMESPACE,
+                        BundleCapabilityImpl.PACKAGE_NAMESPACE,
                         clauses.get(clauseIdx).m_dirs,
                         newAttrs));
             }
@@ -1284,19 +1217,13 @@
             // Convert bundle version attribute to VersionRange type.
             for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
             {
-                for (int attrIdx = 0;
-                    attrIdx < clauses.get(clauseIdx).m_attrs.size();
-                    attrIdx++)
+                Object value = clauses.get(clauseIdx).m_attrs.get(
+                    Constants.BUNDLE_VERSION_ATTRIBUTE);
+                if (value != null)
                 {
-                    Attribute attr = clauses.get(clauseIdx).m_attrs.get(attrIdx);
-                    if (attr.getName().equals(Constants.BUNDLE_VERSION_ATTRIBUTE))
-                    {
-                        clauses.get(clauseIdx).m_attrs.set(attrIdx,
-                            new Attribute(
-                                Constants.BUNDLE_VERSION_ATTRIBUTE,
-                                VersionRange.parse(attr.getValue().toString()),
-                                attr.isMandatory()));
-                    }
+                    clauses.get(clauseIdx).m_attrs.put(
+                        Constants.BUNDLE_VERSION_ATTRIBUTE,
+                        VersionRange.parse(value.toString()));
                 }
             }
         }
@@ -1304,30 +1231,35 @@
         return clauses;
     }
 
-    private static List<Requirement> convertRequires(
+    private static List<BundleRequirementImpl> convertRequires(
         List<ParsedHeaderClause> clauses, Module owner)
     {
-        List<Requirement> reqList = new ArrayList();
+        List<BundleRequirementImpl> reqList = new ArrayList();
         for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
         {
-            List<Attribute> attrs = clauses.get(clauseIdx).m_attrs;
-
             for (int pathIdx = 0;
                 pathIdx < clauses.get(clauseIdx).m_paths.size();
                 pathIdx++)
             {
+                // Prepend the bundle symbolic name to the array of attributes.
+                Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
+                // Note that we use a linked hash map here to ensure the
+                // package attribute is first, which will make indexing
+                // more efficient.
+// TODO: OSGi R4.3 - This is a hack...perhaps we should use the standard "key"
+//       notion where namespace is also the name of the key attribute.
                 // Prepend the symbolic name to the array of attributes.
-                List<Attribute> newAttrs = new ArrayList<Attribute>(attrs.size() + 1);
-                newAttrs.add(new Attribute(
+                Map<String, Object> newAttrs = new LinkedHashMap<String, Object>(attrs.size() + 1);
+                newAttrs.put(
                     Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
-                    clauses.get(clauseIdx).m_paths.get(pathIdx), false));
-                newAttrs.addAll(attrs);
+                    clauses.get(clauseIdx).m_paths.get(pathIdx));
+                newAttrs.putAll(attrs);
 
                 // Create package requirement and add to requirement list.
                 reqList.add(
-                    new RequirementImpl(
+                    new BundleRequirementImpl(
                         owner,
-                        Capability.MODULE_NAMESPACE,
+                        BundleCapabilityImpl.MODULE_NAMESPACE,
                         clauses.get(clauseIdx).m_dirs,
                         newAttrs));
             }
@@ -1336,27 +1268,26 @@
         return reqList;
     }
 
-    public static Directive parseExtensionBundleHeader(String header)
+    public static String parseExtensionBundleHeader(String header)
         throws BundleException
     {
         List<ParsedHeaderClause> clauses = parseStandardHeader(header);
 
-        Directive result = null;
+        String result = null;
 
         if (clauses.size() == 1)
         {
             // See if there is the "extension" directive.
-            List<Directive> dirs = clauses.get(0).m_dirs;
-            for (int dirIdx = 0; (result == null) && (dirIdx < dirs.size()); dirIdx++)
+            for (Entry<String, String> entry : clauses.get(0).m_dirs.entrySet())
             {
-                if (Constants.EXTENSION_DIRECTIVE.equals(dirs.get(dirIdx).getName()))
+                if (Constants.EXTENSION_DIRECTIVE.equals(entry.getKey()))
                 {
                     // If the extension directive is specified, make sure
                     // the target is the system bundle.
                     if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)) ||
                         Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)))
                     {
-                        result = (Directive) dirs.get(dirIdx);
+                        return entry.getValue();
                     }
                     else
                     {
@@ -1386,16 +1317,15 @@
                 if (clauses.get(0).m_paths.get(clauseIdx).equals(Constants.ACTIVATION_LAZY))
                 {
                     m_activationPolicy = Module.LAZY_ACTIVATION;
-                    for (int dirIdx = 0; dirIdx < clauses.get(0).m_dirs.size(); dirIdx++)
+                    for (Entry<String, String> entry : clauses.get(0).m_dirs.entrySet())
                     {
-                        Directive dir = clauses.get(0).m_dirs.get(dirIdx);
-                        if (dir.getName().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
+                        if (entry.getKey().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
                         {
-                            m_activationIncludeDir = (String) dir.getValue();
+                            m_activationIncludeDir = entry.getValue();
                         }
-                        else if (dir.getName().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
+                        else if (entry.getKey().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
                         {
-                            m_activationExcludeDir = (String) dir.getValue();
+                            m_activationExcludeDir = entry.getValue();
                         }
                     }
                     break;
@@ -1471,8 +1401,8 @@
         }
 
         // Parse the directives/attributes.
-        Map<String, Directive> dirsMap = new HashMap();
-        Map<String, Attribute> attrsMap = new HashMap();
+        Map<String, String> dirs = new HashMap<String, String>();
+        Map<String, Object> attrs = new HashMap<String, Object>();
         int idx = -1;
         String sep = null;
         for (int pieceIdx = pathCount; pieceIdx < pieces.size(); pieceIdx++)
@@ -1506,36 +1436,25 @@
             if (sep.equals(FelixConstants.DIRECTIVE_SEPARATOR))
             {
                 // Check for duplicates.
-                if (dirsMap.get(key) != null)
+                if (dirs.get(key) != null)
                 {
                     throw new IllegalArgumentException(
                         "Duplicate directive: " + key);
                 }
-                dirsMap.put(key, new Directive(key, value));
+                dirs.put(key, value);
             }
             else
             {
                 // Check for duplicates.
-                if (attrsMap.get(key) != null)
+                if (attrs.get(key) != null)
                 {
                     throw new IllegalArgumentException(
                         "Duplicate attribute: " + key);
                 }
-                attrsMap.put(key, new Attribute(key, value, false));
+                attrs.put(key, value);
             }
         }
 
-        List<Directive> dirs = new ArrayList<Directive>(dirsMap.size());
-        for (Entry<String, Directive> entry : dirsMap.entrySet())
-        {
-            dirs.add(entry.getValue());
-        }
-        List<Attribute> attrs = new ArrayList<Attribute>(attrsMap.size());
-        for (Entry<String, Attribute> entry : attrsMap.entrySet())
-        {
-            attrs.add(entry.getValue());
-        }
-
         return new ParsedHeaderClause(paths, dirs, attrs);
     }
 
@@ -1633,4 +1552,4 @@
 
         return libList;
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
index 4be3ed8..ab095e5 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ParsedHeaderClause.java
@@ -19,16 +19,16 @@
 package org.apache.felix.framework.util.manifestparser;
 
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Directive;
+import java.util.Map;
 
 public class ParsedHeaderClause
 {
     public final List<String> m_paths;
-    public final List<Directive> m_dirs;
-    public final List<Attribute> m_attrs;
+    public final Map<String, String> m_dirs;
+    public final Map<String, Object> m_attrs;
 
-    public ParsedHeaderClause(List<String> paths, List<Directive> dirs, List<Attribute> attrs)
+    public ParsedHeaderClause(
+        List<String> paths, Map<String, String> dirs, Map<String, Object> attrs)
     {
         m_paths = paths;
         m_dirs = dirs;
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
new file mode 100644
index 0000000..e0809d8
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.wiring;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Set;
+import java.util.Map;
+import java.util.List;
+import java.util.StringTokenizer;
+import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.resolver.Module;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+
+public class BundleCapabilityImpl implements BundleCapability
+{
+    public static final String MODULE_NAMESPACE = "module";
+    public static final String HOST_NAMESPACE = "host";
+    public static final String PACKAGE_NAMESPACE = "package";
+    public static final String SINGLETON_NAMESPACE = "singleton";
+
+    public static final String PACKAGE_ATTR = "package";
+    public static final String VERSION_ATTR = "version";
+
+    private final Module m_module;
+    private final String m_namespace;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+    private final List<String> m_uses;
+    private final List<List<String>> m_includeFilter;
+    private final List<List<String>> m_excludeFilter;
+    private final Set<String> m_mandatory;
+
+    public BundleCapabilityImpl(Module module, String namespace,
+        Map<String, String> dirs, Map<String, Object> attrs)
+    {
+        m_namespace = namespace;
+        m_module = module;
+        m_dirs = Collections.unmodifiableMap(dirs);
+        m_attrs = Collections.unmodifiableMap(attrs);
+
+        // Find all export directives: uses, mandatory, include, and exclude.
+        
+        m_uses = new ArrayList(0);
+        String value = m_dirs.get(Constants.USES_DIRECTIVE);
+        if (value != null)
+        {
+            // Parse these uses directive.
+            StringTokenizer tok = new StringTokenizer(value, ",");
+            while (tok.hasMoreTokens())
+            {
+                m_uses.add(tok.nextToken().trim());
+            }
+        }
+
+        value = m_dirs.get(Constants.INCLUDE_DIRECTIVE);
+        if (value != null)
+        {
+            List<String> filters = ManifestParser.parseDelimitedString(value, ",");
+            m_includeFilter = new ArrayList<List<String>>(filters.size());
+            for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
+            {
+                List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
+                m_includeFilter.add(substrings);
+            }
+        }
+        else
+        {
+            m_includeFilter = null;
+        }
+
+        value = m_dirs.get(Constants.EXCLUDE_DIRECTIVE);
+        if (value != null)
+        {
+            List<String> filters = ManifestParser.parseDelimitedString(value, ",");
+            m_excludeFilter = new ArrayList<List<String>>(filters.size());
+            for (int filterIdx = 0; filterIdx < filters.size(); filterIdx++)
+            {
+                List<String> substrings = SimpleFilter.parseSubstring(filters.get(filterIdx));
+                m_excludeFilter.add(substrings);
+            }
+        }
+        else
+        {
+            m_excludeFilter = null;
+        }
+
+        m_mandatory = new HashSet<String>(0);
+        value = m_dirs.get(Constants.MANDATORY_DIRECTIVE);
+        if (value != null)
+        {
+            List<String> names = ManifestParser.parseDelimitedString(value, ",");
+            for (String name : names)
+            {
+                // If attribute exists, then record it as mandatory.
+                if (m_attrs.containsKey(name))
+                {
+                    m_mandatory.add(name);
+                }
+                // Otherwise, report an error.
+                else
+                {
+                    throw new IllegalArgumentException(
+                        "Mandatory attribute '" + name + "' does not exist.");
+                }
+            }
+        }
+    }
+
+    public Module getModule()
+    {
+        return m_module;
+    }
+
+    public BundleRevision getRevision()
+    {
+        return null;
+    }
+
+    public String getNamespace()
+    {
+        return m_namespace;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public boolean isAttributeMandatory(String name)
+    {
+        return !m_mandatory.isEmpty() && m_mandatory.contains(name);
+    }
+
+    public List<String> getUses()
+    {
+        return m_uses;
+    }
+
+    public boolean isIncluded(String name)
+    {
+        if ((m_includeFilter == null) && (m_excludeFilter == null))
+        {
+            return true;
+        }
+
+        // Get the class name portion of the target class.
+        String className = Util.getClassName(name);
+
+        // If there are no include filters then all classes are included
+        // by default, otherwise try to find one match.
+        boolean included = (m_includeFilter == null);
+        for (int i = 0;
+            (!included) && (m_includeFilter != null) && (i < m_includeFilter.size());
+            i++)
+        {
+            included = SimpleFilter.compareSubstring(m_includeFilter.get(i), className);
+        }
+
+        // If there are no exclude filters then no classes are excluded
+        // by default, otherwise try to find one match.
+        boolean excluded = false;
+        for (int i = 0;
+            (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.size());
+            i++)
+        {
+            excluded = SimpleFilter.compareSubstring(m_excludeFilter.get(i), className);
+        }
+        return included && !excluded;
+    }
+
+    public String toString()
+    {
+        if (m_module == null)
+        {
+            return m_attrs.toString();
+        }
+        if (m_namespace.equals(PACKAGE_NAMESPACE))
+        {
+            return "[" + m_module + "] "
+                + m_namespace + "; " + m_attrs.get(PACKAGE_ATTR);
+        }
+        return "[" + m_module + "] " + m_namespace + "; " + m_attrs;
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
similarity index 71%
rename from framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java
rename to framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
index 0f039fe..f64d088 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/RequirementImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
@@ -6,9 +6,9 @@
  * 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
@@ -16,63 +16,80 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.framework.util.manifestparser;
+package org.apache.felix.framework.wiring;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
-import org.apache.felix.framework.capabilityset.Attribute;
-import org.apache.felix.framework.capabilityset.Directive;
-import org.apache.felix.framework.capabilityset.Requirement;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.Module;
 import org.apache.felix.framework.util.VersionRange;
 import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
 
-public class RequirementImpl implements Requirement
+public class BundleRequirementImpl implements BundleRequirement
 {
     private final Module m_module;
     private final String m_namespace;
     private final SimpleFilter m_filter;
     private final boolean m_optional;
-    private final List<Directive> m_dirs;
-    private final List<Directive> m_dirsConst;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
 
-    public RequirementImpl(
+    public BundleRequirementImpl(
         Module module, String namespace,
-        List<Directive> dirs, List<Attribute> attrs)
+        Map<String, String> dirs, Map<String, Object> attrs)
     {
         m_module = module;
         m_namespace = namespace;
-        m_dirs = dirs;
-        m_dirsConst = Collections.unmodifiableList(m_dirs);
+        m_dirs = Collections.unmodifiableMap(dirs);
+        m_attrs = Collections.unmodifiableMap(attrs);
         m_filter = convertToFilter(attrs);
 
         // Find resolution import directives.
         boolean optional = false;
-        for (int dirIdx = 0; dirIdx < m_dirs.size(); dirIdx++)
+        if (m_dirs.containsKey(Constants.RESOLUTION_DIRECTIVE)
+            && m_dirs.get(Constants.RESOLUTION_DIRECTIVE).equals(Constants.RESOLUTION_OPTIONAL))
         {
-            if (m_dirs.get(dirIdx).getName().equals(Constants.RESOLUTION_DIRECTIVE))
-            {
-                optional = m_dirs.get(dirIdx).getValue().equals(Constants.RESOLUTION_OPTIONAL);
-            }
+            optional = true;
         }
         m_optional = optional;
     }
 
-    public Module getModule()
-    {
-        return m_module;
-    }
-
     public String getNamespace()
     {
         return m_namespace;
     }
 
-    public SimpleFilter getFilter()
+    public Map<String, String> getDirectives()
     {
-        return m_filter;
+        return m_dirs;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Module getModule()
+    {
+        return m_module;
+    }
+
+    public BundleRevision getRevision()
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public boolean matches(BundleCapability cap)
+    {
+        return CapabilitySet.matches((BundleCapabilityImpl) cap, getFilter());
     }
 
     public boolean isOptional()
@@ -80,21 +97,9 @@
         return m_optional;
     }
 
-    public Directive getDirective(String name)
+    public SimpleFilter getFilter()
     {
-        for (int i = 0; i < m_dirs.size(); i++)
-        {
-            if (m_dirs.get(i).getName().equals(name))
-            {
-                return m_dirs.get(i);
-            }
-        }
-        return null;
-    }
-
-    public List<Directive> getDirectives()
-    {
-        return m_dirsConst;
+        return m_filter;
     }
 
     public String toString()
@@ -102,23 +107,23 @@
         return "[" + m_module + "] " + m_namespace + "; " + getFilter().toString();
     }
 
-    private static SimpleFilter convertToFilter(List<Attribute> attrs)
+    private static SimpleFilter convertToFilter(Map<String, Object> attrs)
     {
         // Rather than building a filter string to be parsed into a SimpleFilter,
         // we will just create the parsed SimpleFilter directly.
 
         List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
 
-        for (Attribute attr : attrs)
+        for (Entry<String, Object> entry : attrs.entrySet())
         {
-            if (attr.getValue() instanceof VersionRange)
+            if (entry.getValue() instanceof VersionRange)
             {
-                VersionRange vr = (VersionRange) attr.getValue();
+                VersionRange vr = (VersionRange) entry.getValue();
                 if (vr.isFloorInclusive())
                 {
                     filters.add(
                         new SimpleFilter(
-                            attr.getName(),
+                            entry.getKey(),
                             vr.getFloor().toString(),
                             SimpleFilter.GTE));
                 }
@@ -128,7 +133,7 @@
                         new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
                     ((List) not.getValue()).add(
                         new SimpleFilter(
-                            attr.getName(),
+                            entry.getKey(),
                             vr.getFloor().toString(),
                             SimpleFilter.LTE));
                     filters.add(not);
@@ -140,7 +145,7 @@
                     {
                         filters.add(
                             new SimpleFilter(
-                                attr.getName(),
+                                entry.getKey(),
                                 vr.getCeiling().toString(),
                                 SimpleFilter.LTE));
                     }
@@ -150,7 +155,7 @@
                             new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
                         ((List) not.getValue()).add(
                             new SimpleFilter(
-                                attr.getName(),
+                                entry.getKey(),
                                 vr.getCeiling().toString(),
                                 SimpleFilter.GTE));
                         filters.add(not);
@@ -159,12 +164,12 @@
             }
             else
             {
-                List<String> values = SimpleFilter.parseSubstring(attr.getValue().toString());
+                List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
                 if (values.size() > 1)
                 {
                     filters.add(
                         new SimpleFilter(
-                            attr.getName(),
+                            entry.getKey(),
                             values,
                             SimpleFilter.SUBSTRING));
                 }
@@ -172,7 +177,7 @@
                 {
                     filters.add(
                         new SimpleFilter(
-                            attr.getName(),
+                            entry.getKey(),
                             values.get(0),
                             SimpleFilter.EQ));
                 }
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java b/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java
new file mode 100644
index 0000000..c49f0ac
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleCapability.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.framework.wiring;
+
+import java.util.Map;
+
+/**
+ * A capability that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 0fde13c3228af1aa97872b37ccf0aa6e23123b11 $
+ */
+public interface BundleCapability {
+	/**
+	 * Returns the name space of this capability.
+	 * 
+	 * @return The name space of this capability.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this capability.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this capability, or an empty map if this capability has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this capability.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this capability, or an empty map if this capability has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the bundle revision declaring this capability.
+	 * 
+	 * @return The bundle revision declaring this capability.
+	 */
+	BundleRevision getRevision();
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
new file mode 100644
index 0000000..bd637e6
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.framework.wiring;
+
+import java.util.Map;
+
+/**
+ * A requirement that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 659132c1fac7526240df377ead0e1bc8d4af2e77 $
+ */
+public interface BundleRequirement {
+	/**
+	 * Returns the name space of this requirement.
+	 * 
+	 * @return The name space of this requirement.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this requirement.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this requirement.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the bundle revision declaring this requirement.
+	 * 
+	 * @return The bundle revision declaring this requirement.
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns whether the specified capability matches this requirement.
+	 * 
+	 * @param capability The capability to match to this requirement.
+	 * @return {@code true} if the specified capability has the same
+	 *         {@link #getNamespace() name space} as this requirement and the
+	 *         filter for this requirement matches the
+	 *         {@link BundleCapability#getAttributes() attributes of the
+	 *         specified capability}; {@code false} otherwise.
+	 */
+	boolean matches(BundleCapability capability);
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java
new file mode 100644
index 0000000..5924dc1
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleRevision.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.framework.wiring;
+
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/**
+ * Bundle Revision. When a bundle is installed and each time a bundle is
+ * updated, a new bundle revision of the bundle is created. Since a bundle
+ * update can change the entries in a bundle, different bundle wirings for the
+ * same bundle can be associated with different bundle revisions.
+ * 
+ * <p>
+ * For a bundle that has not been uninstalled, the most recent bundle revision
+ * is defined to be the current bundle revision. A bundle in the UNINSTALLED
+ * state does not have a current revision. The current bundle revision for a
+ * bundle can be obtained by calling {@link Bundle#adapt(Class) bundle.adapt}
+ * (BundleRevision.class). Since a bundle in the UNINSTALLED state does not have
+ * a current revision, adapting such a bundle returns {@code null}.
+ * 
+ * <p>
+ * The framework defines name spaces for {@link #PACKAGE_NAMESPACE package},
+ * {@link #BUNDLE_NAMESPACE bundle} and {@link #HOST_NAMESPACE host}
+ * capabilities and requirements. These name spaces are defined only to express
+ * wiring information by the framework. They must not be used in
+ * {@link Constants#PROVIDE_CAPABILITY Provide-Capability} and
+ * {@link Constants#REQUIRE_CAPABILITY Require-Capability} manifest headers.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 139b3046ebd46c48b03dda8d36f2f9d79e2e616d $
+ */
+public interface BundleRevision extends BundleReference {
+	/**
+	 * Returns the symbolic name for this bundle revision.
+	 * 
+	 * @return The symbolic name for this bundle revision.
+	 * @see Bundle#getSymbolicName()
+	 */
+	String getSymbolicName();
+
+	/**
+	 * Returns the version for this bundle revision.
+	 * 
+	 * @return The version for this bundle revision, or
+	 *         {@link Version#emptyVersion} if this bundle revision has no
+	 *         version information.
+	 * @see Bundle#getVersion()
+	 */
+	Version getVersion();
+
+	/**
+	 * Returns the capabilities declared by this bundle revision.
+	 * 
+	 * @param namespace The name space of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all name
+	 *        spaces.
+	 * @return A list containing a snapshot of the declared
+	 *         {@link BundleCapability}s, or an empty list if this bundle
+	 *         revision declares no capabilities in the specified name space.
+	 *         The list contains the declared capabilities in the order they are
+	 *         specified in the manifest.
+	 */
+	List<BundleCapability> getDeclaredCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle revision.
+	 * 
+	 * @param namespace The name space of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all name
+	 *        spaces.
+	 * @return A list containing a snapshot of the declared
+	 *         {@link BundleRequirement}s, or an empty list if this bundle
+	 *         revision declares no requirements in the specified name space.
+	 *         The list contains the declared requirements in the order they are
+	 *         specified in the manifest.
+	 */
+	List<BundleRequirement> getDeclaredRequirements(String namespace);
+
+	/**
+	 * Name space for package capabilities and requirements.
+	 * 
+	 * <p>
+	 * The name of the package is stored in the capability attribute of the same
+	 * name as this name space (osgi.wiring.package). The other
+	 * directives and attributes of the package, from the
+	 * {@link Constants#EXPORT_PACKAGE Export-Package} manifest header, can be
+	 * found in the cabability's {@link BundleCapability#getDirectives()
+	 * directives} and {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
+	 * contain the {@link Version} of the package if one is specified or
+	 * {@link Version#emptyVersion} if not specified. The
+	 * {@link Constants#BUNDLE_SYMBOLICNAME_ATTRIBUTE bundle-symbolic-name}
+	 * capability attribute must contain the
+	 * {@link BundleRevision#getSymbolicName() symbolic name} of the provider if
+	 * one is specified. The {@link Constants#BUNDLE_VERSION_ATTRIBUTE
+	 * bundle-version} capability attribute must contain the
+	 * {@link BundleRevision#getVersion() version} of the provider if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * The package capabilities provided by the system bundle, that is the
+	 * bundle with id zero, must include the package specified by the
+	 * {@link Constants#FRAMEWORK_SYSTEMPACKAGES} and
+	 * {@link Constants#FRAMEWORK_SYSTEMPACKAGES_EXTRA} framework properties as
+	 * well as any other package exported by the framework implementation.
+	 * 
+	 * <p>
+	 * A bundle revision {@link BundleRevision#getDeclaredCapabilities(String)
+	 * declares} zero or more package capabilities (this is, exported packages)
+	 * and {@link BundleRevision#getDeclaredRequirements(String) declares} zero
+	 * or more package requirements.
+	 * <p>
+	 * A bundle wiring {@link BundleWiring#getCapabilities(String) provides}
+	 * zero or more resolved package capabilities (that is, exported packages)
+	 * and {@link BundleWiring#getRequiredWires(String) requires} zero or more
+	 * resolved package requirements (that is, imported packages). The number of
+	 * package wires required by a bundle wiring may change as the bundle wiring
+	 * may dynamically import additional packages.
+	 */
+	String	PACKAGE_NAMESPACE	= "osgi.wiring.package";
+
+	/**
+	 * Name space for bundle capabilities and requirements.
+	 * 
+	 * <p>
+	 * The bundle symbolic name of the bundle is stored in the capability
+	 * attribute of the same name as this name space (osgi.wiring.bundle).
+	 * The other directives and attributes of the bundle, from the
+	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+	 * header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+	 * attribute must contain the {@link Version} of the bundle from the
+	 * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * A non-fragment revision
+	 * {@link BundleRevision#getDeclaredCapabilities(String) declares} exactly
+	 * one<sup>&#8224;</sup> bundle capability (that is, the bundle can be
+	 * required by another bundle). A fragment revision must not declare a
+	 * bundle capability.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision
+	 * {@link BundleWiring#getCapabilities(String) provides} exactly
+	 * one<sup>&#8224;</sup> bundle capability (that is, the bundle can be
+	 * required by another bundle) and
+	 * {@link BundleWiring#getRequiredWires(String) requires} zero or more
+	 * bundle capabilities (that is, requires other bundles).
+	 * 
+	 * <p>
+	 * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
+	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+	 * {@literal <} 2) must not provide a bundle capability.
+	 */
+	String	BUNDLE_NAMESPACE	= "osgi.wiring.bundle";
+
+	/**
+	 * Name space for host capabilities and requirements.
+	 * 
+	 * <p>
+	 * The bundle symbolic name of the bundle is stored in the capability
+	 * attribute of the same name as this name space (osgi.wiring.host).
+	 * The other directives and attributes of the bundle, from the
+	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+	 * header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
+	 * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+	 * attribute must contain the {@link Version} of the bundle from the
+	 * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+	 * specified or {@link Version#emptyVersion} if not specified.
+	 * 
+	 * <p>
+	 * A non-fragment revision
+	 * {@link BundleRevision#getDeclaredCapabilities(String) declares} zero or
+	 * one<sup>&#8224;</sup> host capability if the bundle
+	 * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+	 * attached}. A fragment revision must
+	 * {@link BundleRevision#getDeclaredRequirements(String) declare} exactly
+	 * one host requirement.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision
+	 * {@link BundleWiring#getCapabilities(String) provides} zero or
+	 * one<sup>&#8224;</sup> host capability if the bundle
+	 * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+	 * attached}. A bundle wiring for a fragment revision
+	 * {@link BundleWiring#getRequiredWires(String) requires} a host capability
+	 * for each host to which it is attached.
+	 * 
+	 * <p>
+	 * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
+	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+	 * {@literal <} 2) must not provide a host capability.
+	 */
+	String	HOST_NAMESPACE		= "osgi.wiring.host";
+
+	/**
+	 * Returns the special types of this bundle revision. The bundle revision
+	 * type values are:
+	 * <ul>
+	 * <li>{@link #TYPE_FRAGMENT}
+	 * </ul>
+	 * 
+	 * A bundle revision may be more than one type at a time. A type code is
+	 * used to identify the bundle revision type for future extendability.
+	 * 
+	 * <p>
+	 * If this bundle revision is not one or more of the defined types then 0 is
+	 * returned.
+	 * 
+	 * @return The special types of this bundle revision. The type values are
+	 *         ORed together.
+	 */
+	int getTypes();
+
+	/**
+	 * Bundle revision type indicating the bundle revision is a fragment.
+	 * 
+	 * @see #getTypes()
+	 */
+	int	TYPE_FRAGMENT	= 0x00000001;
+
+	/**
+	 * Returns the bundle wiring which is using this bundle revision.
+	 * 
+	 * @return The bundle wiring which is using this bundle revision or
+	 *         {@code null} if no bundle wiring is using this bundle revision.
+	 * @see BundleWiring#getRevision()
+	 */
+	BundleWiring getWiring();
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java b/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java
new file mode 100644
index 0000000..1b19e4c
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleWire.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.framework.wiring;
+
+/**
+ * A wire connecting a {@link BundleCapability} to a {@link BundleRequirement}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 4f936a84065762ec3267a44f86ae01b0150e44ce $
+ */
+public interface BundleWire {
+	/**
+	 * Returns the {@link BundleCapability} for this wire.
+	 * 
+	 * @return The {@link BundleCapability} for this wire.
+	 */
+	BundleCapability getCapability();
+
+	/**
+	 * Return the {@link BundleRequirement} for this wire.
+	 * 
+	 * @return The {@link BundleRequirement} for this wire.
+	 */
+	BundleRequirement getRequirement();
+
+	/**
+	 * Returns the bundle wiring {@link BundleWiring#getProvidedWires(String)
+	 * providing} the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The bundle revision referenced by the returned bundle wiring may differ
+	 * from the bundle revision reference by the {@link #getCapability()
+	 * capability}.
+	 * 
+	 * @return The bundle wiring providing the capability. If the bundle wiring
+	 *         providing the capability is not {@link BundleWiring#isInUse() in
+	 *         use}, {@code null} will be returned.
+	 */
+	BundleWiring getProviderWiring();
+
+	/**
+	 * Returns the bundle wiring who
+	 * {@link BundleWiring#getRequiredWires(String) requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The bundle revision referenced by the returned bundle wiring may differ
+	 * from the bundle revision reference by the {@link #getRequirement()
+	 * requirement}.
+	 * 
+	 * @return The bundle wiring whose requirement is wired to the capability.
+	 *         If the bundle wiring requiring the capability is not
+	 *         {@link BundleWiring#isInUse() in use}, {@code null} will be
+	 *         returned.
+	 */
+	BundleWiring getRequirerWiring();
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java b/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java
new file mode 100644
index 0000000..8d8956a
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleWiring.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.framework.wiring;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring
+ * for the bundle is created. A bundle wiring is associated with a bundle
+ * revision and represents the dependencies with other bundle wirings.
+ * 
+ * <p>
+ * The bundle wiring for a bundle is the {@link #isCurrent() current} bundle
+ * wiring if it is the most recent bundle wiring for the current bundle
+ * revision. A bundle wiring is {@link #isInUse() in use} if it is the current
+ * bundle wiring or if some other in use bundle wiring is dependent upon it. For
+ * example, another bundle wiring is wired to a capability provided by the
+ * bundle wiring. An in use bundle wiring for a non-fragment bundle has a class
+ * loader. All bundles with non-current, in use bundle wirings are considered
+ * removal pending. Once a bundle wiring is no longer in use, it is considered
+ * stale and is discarded by the framework.
+ * 
+ * <p>
+ * The current bundle wiring for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class). A bundle in the
+ * INSTALLED or UNINSTALLED state does not have a current wiring, adapting such
+ * a bundle returns {@code null}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 58b8ec3bb9649387d4ccba1070f034f217d06ea2 $
+ */
+public interface BundleWiring extends BundleReference {
+	/**
+	 * Returns {@code true} if this bundle wiring is the current bundle wiring.
+	 * The bundle wiring for a bundle is the current bundle wiring if it is the
+	 * most recent bundle wiring for the current bundle revision. All bundles
+	 * with non-current, in use bundle wirings are considered
+	 * {@link FrameworkWiring#getRemovalPendingBundles() removal pending}.
+	 * 
+	 * @return {@code true} if this bundle wiring is the current bundle wiring;
+	 *         {@code false} otherwise.
+	 */
+	boolean isCurrent();
+
+	/**
+	 * Returns {@code true} if this bundle wiring is in use. A bundle wiring is
+	 * in use if it is the {@link #isCurrent() current} wiring or if some other
+	 * in use bundle wiring is dependent upon it. Once a bundle wiring is no
+	 * longer in use, it is considered stale and is discarded by the framework.
+	 * 
+	 * @return {@code true} if this bundle wiring is in use; {@code false}
+	 *         otherwise.
+	 */
+	boolean isInUse();
+
+	/**
+	 * Returns the capabilities provided by this bundle wiring.
+	 * 
+	 * <p>
+	 * A capability may not be required by any bundle wiring and thus there may
+	 * be no {@link #getProvidedWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision provides a subset of the
+	 * declared capabilities from the bundle revision and all attached fragment
+	 * revisions. Not all declared capabilities may be provided since some may
+	 * be discarded. For example, if a package is declared to be exported and
+	 * import, only one is selected and the other is discarded.
+	 * 
+	 * @param namespace The name space of the capabilities to return or
+	 *        {@code null} to return the capabilities from all name spaces.
+	 * @return A list containing a snapshot of the {@link BundleCapability}s, or
+	 *         an empty list if this bundle wiring provides no capabilities in
+	 *         the specified name space. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given name space, the list contains the wires in the order the
+	 *         capabilities were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         capabilities in different name spaces.
+	 */
+	List<BundleCapability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this bundle wiring.
+	 * 
+	 * <p>
+	 * A bundle wiring for a non-fragment revision has a subset of the declared
+	 * requirements from the bundle revision and all attached fragment
+	 * revisions. Not all declared requirements may be present since some may be
+	 * discarded. For example, if a package is declared to be optionally
+	 * imported and is not actually imported, the requirement must be discarded.
+	 * 
+	 * @param namespace The name space of the requirements to return or
+	 *        {@code null} to return the requirements from all name spaces.
+	 * @return A list containing a snapshot of the {@link BundleRequirement}s,
+	 *         or an empty list if this bundle wiring uses no requirements in
+	 *         the specified name space. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given name space, the list contains the wires in the order the
+	 *         requirements were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         requirements in different name spaces.
+	 */
+	List<BundleRequirement> getRequirements(String namespace);
+
+	/**
+	 * Returns the {@link BundleWire}s to the provided {@link BundleCapability
+	 * capabilities} of this bundle wiring.
+	 * 
+	 * @param namespace The name space of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all name spaces.
+	 * @return A list containing a snapshot of the {@link BundleWire}s for the
+	 *         {@link BundleCapability capabilities} of this bundle wiring, or
+	 *         an empty list if this bundle wiring has no capabilities in the
+	 *         specified name space. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given name space, the list contains the wires in the order the
+	 *         capabilities were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         capabilities in different name spaces.
+	 */
+	List<BundleWire> getProvidedWires(String namespace);
+
+	/**
+	 * Returns the {@link BundleWire}s to the {@link BundleRequirement
+	 * requirements} in use by this bundle wiring.
+	 * 
+	 * <p>
+	 * This method may return different results if this bundle wiring adds wires
+	 * to more requirements. For example, dynamically importing a package will
+	 * establish a new wire to the dynamically imported package.
+	 * 
+	 * @param namespace The name space of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all name spaces.
+	 * @return A list containing a snapshot of the {@link BundleWire}s for the
+	 *         {@link BundleRequirement requirements} of this bundle wiring, or
+	 *         an empty list if this bundle wiring has no requirements in the
+	 *         specified name space. If this bundle wiring is not
+	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
+	 *         given name space, the list contains the wires in the order the
+	 *         requirements were specified in the manifests of the
+	 *         {@link #getRevision() bundle revision} and the attached fragments
+	 *         of this bundle wiring. There is no ordering defined between
+	 *         requirements in different name spaces.
+	 */
+	List<BundleWire> getRequiredWires(String namespace);
+
+	/**
+	 * Returns the bundle revision for the bundle in this bundle wiring. Since a
+	 * bundle update can change the entries in a bundle, different bundle
+	 * wirings for the same bundle can have different bundle revisions.
+	 * 
+	 * <p>
+	 * The bundle object {@link BundleReference#getBundle() referenced} by the
+	 * returned {@code BundleRevision} may return different information than the
+	 * returned {@code BundleRevision} since the returned {@code BundleRevision}
+	 * may refer to an older revision of the bundle.
+	 * 
+	 * @return The bundle revision for this bundle wiring.
+	 * @see BundleRevision#getWiring()
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns the class loader for this bundle wiring. Since a bundle refresh
+	 * creates a new bundle wiring for a bundle, different bundle wirings for
+	 * the same bundle will have different class loaders.
+	 * 
+	 * @return The class loader for this bundle wiring. If this bundle wiring is
+	 *         not {@link #isInUse() in use} or this bundle wiring is for a
+	 *         fragment revision, {@code null} will be returned.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code RuntimePermission("getClassLoader")}, and the Java Runtime
+	 *         Environment supports permissions.
+	 */
+	ClassLoader getClassLoader();
+
+	/**
+	 * Returns entries in this bundle wiring's {@link #getRevision() bundle
+	 * revision} and its attached fragment revisions. This bundle wiring's class
+	 * loader is not used to search for entries. Only the contents of this
+	 * bundle wiring's bundle revision and its attached fragment revisions are
+	 * searched for the specified entries.
+	 * 
+	 * <p>
+	 * This method takes into account that the &quot;contents&quot; of this
+	 * bundle wiring can have attached fragments. This &quot;bundle space&quot;
+	 * is not a name space with unique members; the same entry name can be
+	 * present multiple times. This method therefore returns a list of URL
+	 * objects. These URLs can come from different JARs but have the same path
+	 * name. This method can either return only entries in the specified path or
+	 * recurse into subdirectories returning entries in the directory tree
+	 * beginning at the specified path.
+	 * 
+	 * <p>
+	 * Note: Jar and zip files are not required to include directory entries.
+	 * URLs to directory entries will not be returned if the bundle contents do
+	 * not contain directory entries.
+	 * 
+	 * @param path The path name in which to look. The path is always relative
+	 *        to the root of this bundle wiring and may begin with
+	 *        &quot;/&quot;. A path value of &quot;/&quot; indicates the root of
+	 *        this bundle wiring.
+	 * @param filePattern The file name pattern for selecting entries in the
+	 *        specified path. The pattern is only matched against the last
+	 *        element of the entry path. If the entry is a directory then the
+	 *        trailing &quot;/&quot; is not used for pattern matching. Substring
+	 *        matching is supported, as specified in the Filter specification,
+	 *        using the wildcard character (&quot;*&quot;). If {@code null} is
+	 *        specified, this is equivalent to &quot;*&quot; and matches all
+	 *        files.
+	 * @param options The options for listing resource names. See
+	 *        {@link #FINDENTRIES_RECURSE}. The method must ignore unrecognized
+	 *        options.
+	 * @return An unmodifiable list of URL objects for each matching entry, or
+	 *         an empty list if no matching entry could be found, if this bundle
+	 *         wiring is for a fragment revision or if the caller does not have
+	 *         the appropriate {@code AdminPermission[bundle,RESOURCE]} and the
+	 *         Java Runtime Environment supports permissions. The list is
+	 *         ordered such that entries from the {@link #getRevision() bundle
+	 *         revision} are returned first followed by the entries from
+	 *         attached fragment revisions in attachment order. If this bundle
+	 *         wiring is not {@link #isInUse() in use}, {@code null} must be
+	 *         returned.
+	 * @see Bundle#findEntries(String, String, boolean)
+	 */
+	List<URL> findEntries(String path, String filePattern, int options);
+
+	/**
+	 * The find entries operation must recurse into subdirectories.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #findEntries(String, String, int)} to specify the result must
+	 * include the matching entries from the specified path and its
+	 * subdirectories. If this bit is not set, then the result must only include
+	 * matching entries from the specified path.
+	 * 
+	 * @see #findEntries(String, String, int)
+	 */
+	int	FINDENTRIES_RECURSE	= 0x00000001;
+
+	/**
+	 * Returns the names of resources visible to this bundle wiring's
+	 * {@link #getClassLoader() class loader}. The returned names can be used to
+	 * access the resources via this bundle wiring's class loader.
+	 * 
+	 * <ul>
+	 * <li>Only the resource names for resources in bundle wirings will be
+	 * returned. The names of resources visible to a bundle wiring's parent
+	 * class loader, such as the bootstrap class loader, must not be included in
+	 * the result.
+	 * <li>Only established wires will be examined for resources. This method
+	 * must not cause new wires for dynamic imports to be established.
+	 * </ul>
+	 * 
+	 * @param path The path name in which to look. The path is always relative
+	 *        to the root of this bundle wiring's class loader and may begin
+	 *        with &quot;/&quot;. A path value of &quot;/&quot; indicates the
+	 *        root of this bundle wiring's class loader.
+	 * @param filePattern The file name pattern for selecting resource names in
+	 *        the specified path. The pattern is only matched against the last
+	 *        element of the resource path. If the resource is a directory then
+	 *        the trailing &quot;/&quot; is not used for pattern matching.
+	 *        Substring matching is supported, as specified in the Filter
+	 *        specification, using the wildcard character (&quot;*&quot;). If
+	 *        {@code null} is specified, this is equivalent to &quot;*&quot; and
+	 *        matches all files.
+	 * @param options The options for listing resource names. See
+	 *        {@link #LISTRESOURCES_LOCAL} and {@link #LISTRESOURCES_RECURSE}.
+	 *        This method must ignore unrecognized options.
+	 * @return An unmodifiable collection of resource names for each matching
+	 *         resource, or an empty collection if no matching resource could be
+	 *         found, if this bundle wiring is for a fragment revision or if the
+	 *         caller does not have the appropriate
+	 *         {@code AdminPermission[bundle,RESOURCE]} and the Java Runtime
+	 *         Environment supports permissions. The collection is unordered and
+	 *         must contain no duplicate resource names. If this bundle wiring
+	 *         is not {@link #isInUse() in use}, {@code null} must be returned.
+	 */
+	Collection<String> listResources(String path, String filePattern,
+			int options);
+
+	/**
+	 * The list resource names operation must recurse into subdirectories.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #listResources(String, String, int)} to specify the result must
+	 * include the names of matching resources from the specified path and its
+	 * subdirectories. If this bit is not set, then the result must only include
+	 * names of matching resources from the specified path.
+	 * 
+	 * @see #listResources(String, String, int)
+	 */
+	int	LISTRESOURCES_RECURSE	= 0x00000001;
+
+	/**
+	 * The list resource names operation must limit the result to the names of
+	 * matching resources contained in this bundle wiring's
+	 * {@link #getRevision() bundle revision} and its attached fragment
+	 * revisions. The result must not include resource names for resources in
+	 * {@link BundleRevision#PACKAGE_NAMESPACE package} names which are
+	 * {@link #getRequiredWires(String) imported} by this wiring.
+	 * 
+	 * <p>
+	 * This bit may be set when calling
+	 * {@link #listResources(String, String, int)} to specify the result must
+	 * only include the names of matching resources contained in this bundle
+	 * wiring's bundle revision and its attached fragment revisions. If this bit
+	 * is not set, then the result must include the names of matching resources
+	 * reachable from this bundle wiring's class loader which may include the
+	 * names of matching resources contained in imported packages and required
+	 * bundles.
+	 * 
+	 * @see #listResources(String, String, int)
+	 */
+	int	LISTRESOURCES_LOCAL		= 0x00000002;
+}