diff --git a/resolver/pom.xml b/resolver/pom.xml
new file mode 100644
index 0000000..f1b2f49
--- /dev/null
+++ b/resolver/pom.xml
@@ -0,0 +1,112 @@
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix-parent</artifactId>
+    <version>2.1</version>
+    <relativePath>../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix Resolver</name>
+  <description>
+    Provide OSGi resolver service.
+  </description>
+  <version>0.1.0-SNAPSHOT</version>
+  <artifactId>org.apache.felix.resolver</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>5.0.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <target>jsr14</target>
+          <source>1.5</source>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>buildnumber-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>validate</phase>
+            <goals>
+              <goal>create</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <doCheck>false</doCheck>
+          <doUpdate>true</doUpdate>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>2.3.7</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <_sources>true</_sources>
+            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+            <Bundle-Version>0.1.0.r${buildNumber}</Bundle-Version>
+            <Bundle-Activator>
+              org.apache.felix.resolver.Activator
+            </Bundle-Activator>
+            <Private-Package>org.apache.*</Private-Package>
+            <Export-Package>
+              org.osgi.service.resolver.*;provide:=true
+            </Export-Package>
+            <Import-Package>
+              org.osgi.resource.*;provide:=true, *
+            </Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <includes>
+            <include>src/**</include>
+          </includes>
+          <excludes>
+            <exclude>src/**/packageinfo</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Activator.java b/resolver/src/main/java/org/apache/felix/resolver/Activator.java
new file mode 100644
index 0000000..0d1c262
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/Activator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.resolver;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.resolver.Resolver;
+
+public class Activator implements BundleActivator
+{
+    public static final String LOG_LEVEL = "felix.resolver.log.level";
+
+    public void start(BundleContext bc) throws Exception
+    {
+        int logLevel = 4;
+        if (bc.getProperty(LOG_LEVEL) != null)
+        {
+            try
+            {
+                logLevel = Integer.parseInt(bc.getProperty(LOG_LEVEL));
+            }
+            catch (NumberFormatException ex)
+            {
+                // Use default log level.
+            }
+        }
+        bc.registerService(
+            Resolver.class,
+            new ResolverImpl(new Logger(logLevel)),
+            null);
+    }
+
+    public void stop(BundleContext bc) throws Exception
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Candidates.java b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
new file mode 100644
index 0000000..b3dc3e2
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
@@ -0,0 +1,1049 @@
+/*
+ * 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.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.resolver.ResolveContext;
+
+class Candidates
+{
+    public static final int MANDATORY = 0;
+    public static final int OPTIONAL = 1;
+    public static final int ON_DEMAND = 2;
+
+    private final Set<Resource> m_mandatoryResources;
+    // Maps a capability to requirements that match it.
+    private final Map<Capability, Set<Requirement>> m_dependentMap;
+    // Maps a requirement to the capability it matches.
+    private final Map<Requirement, List<Capability>> m_candidateMap;
+    // Maps a bundle revision to its associated wrapped revision; this only happens
+    // when a revision being resolved has fragments to attach to it.
+    private final Map<Resource, WrappedResource> m_allWrappedHosts;
+    // Map used when populating candidates to hold intermediate and final results.
+    private final Map<Resource, Object> m_populateResultCache;
+
+    // Flag to signal if fragments are present in the candidate map.
+    private boolean m_fragmentsPresent = false;
+
+    /**
+     * Private copy constructor used by the copy() method.
+     * @param dependentMap the capability dependency map.
+     * @param candidateMap the requirement candidate map.
+     * @param hostFragments the fragment map.
+     * @param wrappedHosts the wrapped hosts map.
+    **/
+    private Candidates(
+        Set<Resource> mandatoryResources,
+        Map<Capability, Set<Requirement>> dependentMap,
+        Map<Requirement, List<Capability>> candidateMap,
+        Map<Resource, WrappedResource> wrappedHosts, Map<Resource, Object> populateResultCache,
+        boolean fragmentsPresent)
+    {
+        m_mandatoryResources = mandatoryResources;
+        m_dependentMap = dependentMap;
+        m_candidateMap = candidateMap;
+        m_allWrappedHosts = wrappedHosts;
+        m_populateResultCache = populateResultCache;
+        m_fragmentsPresent = fragmentsPresent;
+    }
+
+    /**
+     * Constructs an empty Candidates object.
+    **/
+    public Candidates()
+    {
+        m_mandatoryResources = new HashSet<Resource>();
+        m_dependentMap = new HashMap<Capability, Set<Requirement>>();
+        m_candidateMap = new HashMap<Requirement, List<Capability>>();
+        m_allWrappedHosts = new HashMap<Resource, WrappedResource>();
+        m_populateResultCache = new HashMap<Resource, Object>();
+    }
+
+    /**
+     * Populates candidates for the specified revision. How a revision is
+     * resolved depends on its resolution type as follows:
+     * <ul>
+     *   <li><tt>MANDATORY</tt> - must resolve and failure to do so throws
+     *       an exception.</li>
+     *   <li><tt>OPTIONAL</tt> - attempt to resolve, but no exception is thrown
+     *       if the resolve fails.</li>
+     *   <li><tt>ON_DEMAND</tt> - only resolve on demand; this only applies to
+     *       fragments and will only resolve a fragment if its host is already
+     *       selected as a candidate.</li>
+     * </ul>
+     * @param state the resolver state used for populating the candidates.
+     * @param revision the revision whose candidates should be populated.
+     * @param resolution indicates the resolution type.
+     */
+    public final void populate(
+        ResolveContext rc, Resource resource, int resolution) throws ResolutionException
+    {
+        // Get the current result cache value, to make sure the revision
+        // hasn't already been populated.
+        Object cacheValue = m_populateResultCache.get(resource);
+        // Has been unsuccessfully populated.
+        if (cacheValue instanceof ResolutionException)
+        {
+            return;
+        }
+        // Has been successfully populated.
+        else if (cacheValue instanceof Boolean)
+        {
+            return;
+        }
+
+        // We will always attempt to populate fragments, since this is necessary
+        // for ondemand attaching of fragment. However, we'll only attempt to
+        // populate optional non-fragment revisions if they aren't already
+        // resolved.
+        boolean isFragment = Util.isFragment(resource);
+        if (!isFragment && rc.getWirings().containsKey(resource))
+        {
+            return;
+        }
+
+        // Always attempt to populate mandatory or optional revisions.
+        // However, for on-demand fragments only populate if their host
+        // is already populated.
+        if ((resolution != ON_DEMAND)
+            || (isFragment && populateFragmentOndemand(rc, resource)))
+        {
+            if (resolution == MANDATORY)
+            {
+                m_mandatoryResources.add(resource);
+            }
+            try
+            {
+                // Try to populate candidates for the optional revision.
+                populateResource(rc, resource);
+            }
+            catch (ResolutionException ex)
+            {
+                // Only throw an exception if resolution is mandatory.
+                if (resolution == MANDATORY)
+                {
+                    throw ex;
+                }
+            }
+        }
+    }
+
+    /**
+     * Populates candidates for the specified revision.
+     * @param state the resolver state used for populating the candidates.
+     * @param revision the revision whose candidates should be populated.
+     */
+// TODO: FELIX3 - Modify to not be recursive.
+    private void populateResource(ResolveContext rc, Resource resource) throws ResolutionException
+    {
+        // Determine if we've already calculated this revision's candidates.
+        // The result cache will have one of three values:
+        //   1. A resolve exception if we've already attempted to populate the
+        //      revision's candidates but were unsuccessful.
+        //   2. Boolean.TRUE indicating we've already attempted to populate the
+        //      revision's candidates and were successful.
+        //   3. An array containing the cycle count, current map of candidates
+        //      for already processed requirements, and a list of remaining
+        //      requirements whose candidates still need to be calculated.
+        // For case 1, rethrow the exception. For case 2, simply return immediately.
+        // For case 3, this means we have a cycle so we should continue to populate
+        // the candidates where we left off and not record any results globally
+        // until we've popped completely out of the cycle.
+
+        // Keeps track of the number of times we've reentered this method
+        // for the current revision.
+        Integer cycleCount = null;
+
+        // Keeps track of the candidates we've already calculated for the
+        // current revision's requirements.
+        Map<Requirement, List<Capability>> localCandidateMap = null;
+
+        // Keeps track of the current revision's requirements for which we
+        // haven't yet found candidates.
+        List<Requirement> remainingReqs = null;
+
+        // Get the cache value for the current revision.
+        Object cacheValue = m_populateResultCache.get(resource);
+
+        // This is case 1.
+        if (cacheValue instanceof ResolutionException)
+        {
+            throw (ResolutionException) cacheValue;
+        }
+        // This is case 2.
+        else if (cacheValue instanceof Boolean)
+        {
+            return;
+        }
+        // This is case 3.
+        else if (cacheValue != null)
+        {
+            // Increment and get the cycle count.
+            cycleCount = (Integer)
+                (((Object[]) cacheValue)[0]
+                    = new Integer(((Integer) ((Object[]) cacheValue)[0]).intValue() + 1));
+            // Get the already populated candidates.
+            localCandidateMap = (Map) ((Object[]) cacheValue)[1];
+            // Get the remaining requirements.
+            remainingReqs = (List) ((Object[]) cacheValue)[2];
+        }
+
+        // If there is no cache value for the current revision, then this is
+        // the first time we are attempting to populate its candidates, so
+        // do some one-time checks and initialization.
+        if ((remainingReqs == null) && (localCandidateMap == null))
+        {
+            // Record cycle count.
+            cycleCount = new Integer(0);
+
+            // Create a local map for populating candidates first, just in case
+            // the revision is not resolvable.
+            localCandidateMap = new HashMap();
+
+            // Create a modifiable list of the revision's requirements.
+            remainingReqs = new ArrayList(resource.getRequirements(null));
+
+            // Add these value to the result cache so we know we are
+            // in the middle of populating candidates for the current
+            // revision.
+            m_populateResultCache.put(resource,
+                cacheValue = new Object[] { cycleCount, localCandidateMap, remainingReqs });
+        }
+
+        // If we have requirements remaining, then find candidates for them.
+        while (!remainingReqs.isEmpty())
+        {
+            Requirement req = remainingReqs.remove(0);
+
+            // Ignore non-effective and dynamic requirements.
+            String resolution = req.getDirectives()
+                .get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+            if (!rc.isEffective(req)
+                || ((resolution != null)
+                    && resolution.equals(PackageNamespace.RESOLUTION_DYNAMIC)))
+            {
+                continue;
+            }
+
+            // Process the candidates, removing any candidates that
+            // cannot resolve.
+            List<Capability> candidates = rc.findProviders(req);
+            ResolutionException rethrow = processCandidates(rc, resource, candidates);
+
+            // First, due to cycles, makes sure we haven't already failed in
+            // a deeper recursion.
+            Object result = m_populateResultCache.get(resource);
+            if (result instanceof ResolutionException)
+            {
+                throw (ResolutionException) result;
+            }
+            // Next, if are no candidates remaining and the requirement is not
+            // not optional, then record and throw a resolve exception.
+            else if (candidates.isEmpty() && !Util.isOptional(req))
+            {
+                String msg = "Unable to resolve " + resource
+                    + ": missing requirement " + req;
+                if (rethrow != null)
+                {
+                    msg = msg + " [caused by: " + rethrow.getMessage() + "]";
+                }
+                rethrow = new ResolutionException(msg, null, Collections.singleton(req));
+                m_populateResultCache.put(resource, rethrow);
+                throw rethrow;
+            }
+            // Otherwise, if we actually have candidates for the requirement, then
+            // add them to the local candidate map.
+            else if (candidates.size() > 0)
+            {
+                localCandidateMap.put(req, candidates);
+            }
+        }
+
+        // If we are exiting from a cycle then decrement
+        // cycle counter, otherwise record the result.
+        if (cycleCount.intValue() > 0)
+        {
+            ((Object[]) cacheValue)[0] = new Integer(cycleCount.intValue() - 1);
+        }
+        else if (cycleCount.intValue() == 0)
+        {
+            // Record that the revision was successfully populated.
+            m_populateResultCache.put(resource, Boolean.TRUE);
+
+            // Merge local candidate map into global candidate map.
+            if (localCandidateMap.size() > 0)
+            {
+                add(localCandidateMap);
+            }
+        }
+    }
+
+    private boolean populateFragmentOndemand(ResolveContext rc, Resource resource)
+        throws ResolutionException
+    {
+        // Create a modifiable list of the revision's requirements.
+        List<Requirement> remainingReqs =
+            new ArrayList(resource.getRequirements(null));
+        // Find the host requirement.
+        Requirement hostReq = null;
+        for (Iterator<Requirement> it = remainingReqs.iterator();
+            it.hasNext(); )
+        {
+            Requirement r = it.next();
+            if (r.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
+            {
+                hostReq = r;
+                it.remove();
+                break;
+            }
+        }
+        // Get candidates hosts and keep any that have been populated.
+        List<Capability> hosts = rc.findProviders(hostReq);
+        for (Iterator<Capability> it = hosts.iterator(); it.hasNext(); )
+        {
+            Capability host = it.next();
+            if (!isPopulated(host.getResource()))
+            {
+                it.remove();
+            }
+        }
+        // If there aren't any populated hosts, then we can just
+        // return since this fragment isn't needed.
+        if (hosts.isEmpty())
+        {
+            return false;
+        }
+
+        // If there are populated host candidates, then prepopulate
+        // the result cache with the work we've done so far.
+        // Record cycle count, but start at -1 since it will
+        // be incremented again in populate().
+        Integer cycleCount = new Integer(-1);
+        // Create a local map for populating candidates first, just in case
+        // the revision is not resolvable.
+        Map<Requirement, List<Capability>> localCandidateMap =
+            new HashMap<Requirement, List<Capability>>();
+        // Add the discovered host candidates to the local candidate map.
+        localCandidateMap.put(hostReq, hosts);
+        // Add these value to the result cache so we know we are
+        // in the middle of populating candidates for the current
+        // revision.
+        m_populateResultCache.put(resource,
+            new Object[] { cycleCount, localCandidateMap, remainingReqs });
+        return true;
+    }
+
+    public void populateDynamic(
+        ResolveContext rc, Resource resource,
+        Requirement req, List<Capability> candidates) throws ResolutionException
+    {
+        // Record the revision associated with the dynamic require
+        // as a mandatory revision.
+        m_mandatoryResources.add(resource);
+
+        // Add the dynamic imports candidates.
+        add(req, candidates);
+
+        // Process the candidates, removing any candidates that
+        // cannot resolve.
+        ResolutionException rethrow = processCandidates(rc, resource, candidates);
+
+        if (candidates.isEmpty())
+        {
+            if (rethrow == null)
+            {
+                rethrow = new ResolutionException(
+                    "Dynamic import failed.", null, Collections.singleton(req));
+            }
+            throw rethrow;
+        }
+
+        m_populateResultCache.put(resource, Boolean.TRUE);
+    }
+
+    /**
+     * This method performs common processing on the given set of candidates.
+     * Specifically, it removes any candidates which cannot resolve and it
+     * synthesizes candidates for any candidates coming from any attached
+     * fragments, since fragment capabilities only appear once, but technically
+     * each host represents a unique capability.
+     * @param state the resolver state.
+     * @param revision the revision being resolved.
+     * @param candidates the candidates to process.
+     * @return a resolve exception to be re-thrown, if any, or null.
+     */
+    private ResolutionException processCandidates(
+        ResolveContext rc,
+        Resource resource,
+        List<Capability> candidates)
+    {
+        // Get satisfying candidates and populate their candidates if necessary.
+        ResolutionException rethrow = null;
+        Set<Capability> fragmentCands = null;
+        for (Iterator<Capability> itCandCap = candidates.iterator();
+            itCandCap.hasNext(); )
+        {
+            Capability candCap = itCandCap.next();
+
+            boolean isFragment = Util.isFragment(candCap.getResource());
+
+            // If the capability is from a fragment, then record it
+            // because we have to insert associated host capabilities
+            // if the fragment is already attached to any hosts.
+            if (isFragment)
+            {
+                if (fragmentCands == null)
+                {
+                    fragmentCands = new HashSet<Capability>();
+                }
+                fragmentCands.add(candCap);
+            }
+
+            // If the candidate revision is a fragment, then always attempt
+            // to populate candidates for its dependency, since it must be
+            // attached to a host to be used. Otherwise, if the candidate
+            // revision is not already resolved and is not the current version
+            // we are trying to populate, then populate the candidates for
+            // its dependencies as well.
+            // NOTE: Technically, we don't have to check to see if the
+            // candidate revision is equal to the current revision, but this
+            // saves us from recursing and also simplifies exceptions messages
+            // since we effectively chain exception messages for each level
+            // of recursion; thus, any avoided recursion results in fewer
+            // exceptions to chain when an error does occur.
+            if ((isFragment || !rc.getWirings().containsKey(candCap.getResource()))
+                && !candCap.getResource().equals(resource))
+            {
+                try
+                {
+                    populateResource(rc, candCap.getResource());
+                }
+                catch (ResolutionException ex)
+                {
+                    if (rethrow == null)
+                    {
+                        rethrow = ex;
+                    }
+                    // Remove the candidate since we weren't able to
+                    // populate its candidates.
+                    itCandCap.remove();
+                }
+            }
+        }
+
+        // If any of the candidates for the requirement were from a fragment,
+        // then also insert synthesized hosted capabilities for any other host
+        // to which the fragment is attached since they are all effectively
+        // unique capabilities.
+        if (fragmentCands != null)
+        {
+            for (Capability fragCand : fragmentCands)
+            {
+                // Only necessary for resolved fragments.
+                Wiring wiring = rc.getWirings().get(fragCand.getResource());
+                if (wiring != null)
+                {
+                    // Fragments only have host wire, so each wire represents
+                    // an attached host.
+                    for (Wire wire : wiring.getRequiredResourceWires(null))
+                    {
+                        // If the capability is a package, then make sure the
+                        // host actually provides it in its resolved capabilities,
+                        // since it may be a substitutable export.
+                        if (!fragCand.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE)
+                            || rc.getWirings().get(wire.getProvider())
+                                .getResourceCapabilities(null).contains(fragCand))
+                        {
+                            // Note that we can just add this as a candidate
+                            // directly, since we know it is already resolved.
+                            // NOTE: We are synthesizing a hosted capability here,
+                            // but we are not using a ShadowList like we do when
+                            // we synthesizing capabilities for unresolved hosts.
+                            // It is not necessary to use the ShadowList here since
+                            // the host is resolved, because in that case we can
+                            // calculate the proper package space by traversing
+                            // the wiring. In the unresolved case, this isn't possible
+                            // so we need to use the ShadowList so we can keep
+                            // a reference to a synthesized resource with attached
+                            // fragments so we can correctly calculate its package
+                            // space.
+                            rc.insertHostedCapability(
+                                candidates,
+                                new WrappedCapability(
+                                    wire.getCapability().getResource(),
+                                    fragCand));
+                        }
+                    }
+                }
+            }
+        }
+
+        return rethrow;
+    }
+
+    public boolean isPopulated(Resource resource)
+    {
+        Object value = m_populateResultCache.get(resource);
+        return ((value != null) && (value instanceof Boolean));
+    }
+
+    public ResolutionException getResolveException(Resource resource)
+    {
+        Object value = m_populateResultCache.get(resource);
+        return ((value != null) && (value instanceof ResolutionException))
+            ? (ResolutionException) value : null;
+    }
+
+    /**
+     * Adds a requirement and its matching candidates to the internal data
+     * structure. This method assumes it owns the data being passed in and
+     * does not make a copy. It takes the data and processes, such as calculating
+     * which requirements depend on which capabilities and recording any fragments
+     * it finds for future merging.
+     * @param req the requirement to add.
+     * @param candidates the candidates matching the requirement.
+    **/
+    private void add(Requirement req, List<Capability> candidates)
+    {
+        if (req.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
+        {
+            m_fragmentsPresent = true;
+        }
+
+        // Record the candidates.
+        m_candidateMap.put(req, candidates);
+    }
+
+    /**
+     * Adds requirements and candidates in bulk. The outer map is not retained
+     * by this method, but the inner data structures are, so they should not
+     * be further modified by the caller.
+     * @param candidates the bulk requirements and candidates to add.
+    **/
+    private void add(Map<Requirement, List<Capability>> candidates)
+    {
+        for (Entry<Requirement, List<Capability>> entry : candidates.entrySet())
+        {
+            add(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Returns the wrapped module associated with the given module. If the module
+     * was not wrapped, then the module itself is returned. This is really only
+     * needed to determine if the root modules of the resolve have been wrapped.
+     * @param m the module whose wrapper is desired.
+     * @return the wrapper module or the module itself if it was not wrapped.
+    **/
+    public Resource getWrappedHost(Resource r)
+    {
+        Resource wrapped = m_allWrappedHosts.get(r);
+        return (wrapped == null) ? r : wrapped;
+    }
+
+    /**
+     * Gets the candidates associated with a given requirement.
+     * @param req the requirement whose candidates are desired.
+     * @return the matching candidates or null.
+    **/
+    public List<Capability> getCandidates(Requirement req)
+    {
+        return m_candidateMap.get(req);
+    }
+
+    /**
+     * Merges fragments into their hosts. It does this by wrapping all host
+     * modules and attaching their selected fragments, removing all unselected
+     * fragment modules, and replacing all occurrences of the original fragments
+     * in the internal data structures with the wrapped host modules instead.
+     * Thus, fragment capabilities and requirements are merged into the appropriate
+     * host and the candidates for the fragment now become candidates for the host.
+     * Likewise, any module depending on a fragment now depend on the host. Note
+     * that this process is sort of like multiplication, since one fragment that
+     * can attach to two hosts effectively gets multiplied across the two hosts.
+     * So, any modules being satisfied by the fragment will end up having the
+     * two hosts as potential candidates, rather than the single fragment.
+     * @param existingSingletons existing resolved singletons.
+     * @throws ResolveException if the removal of any unselected fragments result
+     *         in the root module being unable to resolve.
+    **/
+    public void prepare(ResolveContext rc) throws ResolutionException
+    {
+        // 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.
+        Map<Capability, Map<String, Map<Version, List<Requirement>>>>
+            hostFragments = Collections.EMPTY_MAP;
+        if (m_fragmentsPresent)
+        {
+            hostFragments = populateDependents();
+        }
+
+        // This method performs the following steps:
+        // 1. Select the fragments to attach to a given host.
+        // 2. Wrap hosts and attach fragments.
+        // 3. Remove any unselected fragments. This is necessary because
+        //    other revisions may depend on the capabilities of unselected
+        //    fragments, so we need to remove the unselected fragments and
+        //    any revisions that depends on them, which could ultimately cause
+        //    the entire resolve to fail.
+        // 4. Replace all fragments with any host it was merged into
+        //    (effectively multiplying it).
+        //    * This includes setting candidates for attached fragment
+        //      requirements as well as replacing fragment capabilities
+        //      with host's attached fragment capabilities.
+
+        // Steps 1 and 2
+        List<WrappedResource> hostResources = new ArrayList<WrappedResource>();
+        List<Resource> unselectedFragments = new ArrayList<Resource>();
+        for (Entry<Capability, Map<String, Map<Version, List<Requirement>>>>
+            hostEntry : hostFragments.entrySet())
+        {
+            // Step 1
+            Capability hostCap = hostEntry.getKey();
+            Map<String, Map<Version, List<Requirement>>> fragments
+                = hostEntry.getValue();
+            List<Resource> selectedFragments = new ArrayList<Resource>();
+            for (Entry<String, Map<Version, List<Requirement>>> fragEntry
+                : fragments.entrySet())
+            {
+                boolean isFirst = true;
+                for (Entry<Version, List<Requirement>> versionEntry
+                    : fragEntry.getValue().entrySet())
+                {
+                    for (Requirement hostReq : versionEntry.getValue())
+                    {
+                        // Selecting the first fragment in each entry, which
+                        // is equivalent to selecting the highest version of
+                        // each fragment with a given symbolic name.
+                        if (isFirst)
+                        {
+                            selectedFragments.add(hostReq.getResource());
+                            isFirst = false;
+                        }
+                        // For any fragment that wasn't selected, remove the
+                        // current host as a potential host for it and remove it
+                        // as a dependent on the host. If there are no more
+                        // potential hosts for the fragment, then mark it as
+                        // unselected for later removal.
+                        else
+                        {
+                            m_dependentMap.get(hostCap).remove(hostReq);
+                            List<Capability> hosts = m_candidateMap.get(hostReq);
+                            hosts.remove(hostCap);
+                            if (hosts.isEmpty())
+                            {
+                                unselectedFragments.add(hostReq.getResource());
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Step 2
+            WrappedResource wrappedHost =
+                new WrappedResource(hostCap.getResource(), selectedFragments);
+            hostResources.add(wrappedHost);
+            m_allWrappedHosts.put(hostCap.getResource(), wrappedHost);
+        }
+
+        // Step 3
+        for (Resource fragment : unselectedFragments)
+        {
+            removeResource(fragment,
+                new ResolutionException(
+                    "Fragment was not selected for attachment: " + fragment));
+        }
+
+        // Step 4
+        for (WrappedResource hostResource : hostResources)
+        {
+            // Replaces capabilities from fragments with the capabilities
+            // from the merged host.
+            for (Capability c : hostResource.getCapabilities(null))
+            {
+                // Don't replace the host capability, since the fragment will
+                // really be attached to the original host, not the wrapper.
+                if (!c.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
+                {
+                    Capability origCap = ((HostedCapability) c).getDeclaredCapability();
+                    // Note that you might think we could remove the original cap
+                    // from the dependent map, but you can't since it may come from
+                    // a fragment that is attached to multiple hosts, so each host
+                    // will need to make their own copy.
+                    Set<Requirement> dependents = m_dependentMap.get(origCap);
+                    if (dependents != null)
+                    {
+                        dependents = new HashSet<Requirement>(dependents);
+                        m_dependentMap.put(c, dependents);
+                        for (Requirement r : dependents)
+                        {
+                            // We have synthesized hosted capabilities for all
+                            // fragments that have been attached to hosts by
+                            // wrapping the host bundle and their attached
+                            // fragments. We need to use the ResolveContext to
+                            // determine the proper priority order for hosted
+                            // capabilities since the order may depend on the
+                            // declaring host/fragment combination. However,
+                            // internally we completely wrap the host revision
+                            // and make all capabilities/requirements point back
+                            // to the wrapped host not the declaring host. The
+                            // ResolveContext expects HostedCapabilities to point
+                            // to the declaring revision, so we need two separate
+                            // candidate lists: one for the ResolveContext with
+                            // HostedCapabilities pointing back to the declaring
+                            // host and one for the resolver with HostedCapabilities
+                            // pointing back to the wrapped host. We ask the
+                            // ResolveContext to insert its appropriate HostedCapability
+                            // into its list, then we mirror the insert into a
+                            // shadow list with the resolver's HostedCapability.
+                            // We only need to ask the ResolveContext to find
+                            // the insert position for fragment caps since these
+                            // were synthesized and we don't know their priority.
+                            // However, in the resolver's candidate list we need
+                            // to replace all caps with the wrapped caps, no
+                            // matter if they come from the host or fragment,
+                            // since we are completing replacing the declaring
+                            // host and fragments with the wrapped host.
+                            List<Capability> cands = m_candidateMap.get(r);
+                            if (!(cands instanceof ShadowList))
+                            {
+                                ShadowList<Capability> shadow =
+                                    new ShadowList<Capability>(cands);
+                                m_candidateMap.put(r, shadow);
+                                cands = shadow;
+                            }
+
+                            // If the original capability is from a fragment, then
+                            // ask the ResolveContext to insert it and update the
+                            // shadow copy of the list accordingly.
+                            if (!origCap.getResource().equals(hostResource.getDeclaredResource()))
+                            {
+                                List<Capability> original = ((ShadowList) cands).getOriginal();
+                                int removeIdx = original.indexOf(origCap);
+                                original.remove(removeIdx);
+                                int insertIdx = rc.insertHostedCapability(
+                                    original,
+                                    new SimpleHostedCapability(
+                                        hostResource.getDeclaredResource(),
+                                        origCap));
+                                cands.remove(removeIdx);
+                                cands.add(insertIdx, c);
+                            }
+                            // If the original capability is from the host, then
+                            // we just need to replace it in the shadow list.
+                            else
+                            {
+                                int idx = cands.indexOf(origCap);
+                                cands.set(idx, c);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Copy candidates for fragment requirements to the host.
+            for (Requirement r : hostResource.getRequirements(null))
+            {
+                Requirement origReq = ((WrappedRequirement) r).getDeclaredRequirement();
+                List<Capability> cands = m_candidateMap.get(origReq);
+                if (cands != null)
+                {
+                    m_candidateMap.put(r, new ArrayList<Capability>(cands));
+                    for (Capability cand : cands)
+                    {
+                        Set<Requirement> dependents = m_dependentMap.get(cand);
+                        dependents.remove(origReq);
+                        dependents.add(r);
+                    }
+                }
+            }
+        }
+
+        // Lastly, verify that all mandatory revisions are still
+        // populated, since some might have become unresolved after
+        // selecting fragments/singletons.
+        for (Resource resource : m_mandatoryResources)
+        {
+            if (!isPopulated(resource))
+            {
+                throw getResolveException(resource);
+            }
+        }
+    }
+
+    // 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 Map<Capability,
+        Map<String, Map<Version, List<Requirement>>>> populateDependents()
+    {
+        Map<Capability, Map<String, Map<Version, List<Requirement>>>>
+            hostFragments = new HashMap<Capability,
+                Map<String, Map<Version, List<Requirement>>>>();
+        for (Entry<Requirement, List<Capability>> entry : m_candidateMap.entrySet())
+        {
+            Requirement req = entry.getKey();
+            List<Capability> caps = entry.getValue();
+            for (Capability cap : caps)
+            {
+                // Record the requirement as dependent on the capability.
+                Set<Requirement> dependents = m_dependentMap.get(cap);
+                if (dependents == null)
+                {
+                    dependents = new HashSet<Requirement>();
+                    m_dependentMap.put(cap, dependents);
+                }
+                dependents.add(req);
+
+                // Keep track of hosts and associated fragments.
+                if (req.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
+                {
+                    String resSymName = Util.getSymbolicName(req.getResource());
+                    Version resVersion = Util.getVersion(req.getResource());
+
+                    Map<String, Map<Version, List<Requirement>>>
+                        fragments = hostFragments.get(cap);
+                    if (fragments == null)
+                    {
+                        fragments = new HashMap<String, Map<Version, List<Requirement>>>();
+                        hostFragments.put(cap, fragments);
+                    }
+                    Map<Version, List<Requirement>> fragmentVersions = fragments.get(resSymName);
+                    if (fragmentVersions == null)
+                    {
+                        fragmentVersions =
+                            new TreeMap<Version, List<Requirement>>(Collections.reverseOrder());
+                        fragments.put(resSymName, fragmentVersions);
+                    }
+                    List<Requirement> actual = fragmentVersions.get(resVersion);
+                    if (actual == null)
+                    {
+                        actual = new ArrayList<Requirement>();
+                        fragmentVersions.put(resVersion, actual);
+                    }
+                    actual.add(req);
+                }
+            }
+        }
+
+        return hostFragments;
+    }
+
+    /**
+     * Removes a module from the internal data structures if it wasn't selected
+     * as a fragment or a singleton. This process may cause other modules to
+     * become unresolved if they depended on the module's capabilities and there
+     * is no other candidate.
+     * @param revision the module to remove.
+     * @throws ResolveException if removing the module caused the resolve to fail.
+    **/
+    private void removeResource(Resource resource, ResolutionException ex)
+        throws ResolutionException
+    {
+        // Add removal reason to result cache.
+        m_populateResultCache.put(resource, ex);
+        // Remove from dependents.
+        Set<Resource> unresolvedResources = new HashSet<Resource>();
+        remove(resource, unresolvedResources);
+        // Remove dependents that failed as a result of removing revision.
+        while (!unresolvedResources.isEmpty())
+        {
+            Iterator<Resource> it = unresolvedResources.iterator();
+            resource = it.next();
+            it.remove();
+            remove(resource, unresolvedResources);
+        }
+    }
+
+    /**
+     * Removes the specified module from the internal data structures, which
+     * involves removing its requirements and its capabilities. This may cause
+     * other modules to become unresolved as a result.
+     * @param br the module to remove.
+     * @param unresolvedRevisions a list to containing any additional modules that
+     *        that became unresolved as a result of removing this module and will
+     *        also need to be removed.
+     * @throws ResolveException if removing the module caused the resolve to fail.
+    **/
+    private void remove(Resource resource, Set<Resource> unresolvedResources)
+        throws ResolutionException
+    {
+        for (Requirement r : resource.getRequirements(null))
+        {
+            remove(r);
+        }
+
+        for (Capability c : resource.getCapabilities(null))
+        {
+            remove(c, unresolvedResources);
+        }
+    }
+
+    /**
+     * Removes a requirement from the internal data structures.
+     * @param req the requirement to remove.
+    **/
+    private void remove(Requirement req)
+    {
+        boolean isFragment = req.getNamespace().equals(HostNamespace.HOST_NAMESPACE);
+
+        List<Capability> candidates = m_candidateMap.remove(req);
+        if (candidates != null)
+        {
+            for (Capability cap : candidates)
+            {
+                Set<Requirement> dependents = m_dependentMap.get(cap);
+                if (dependents != null)
+                {
+                    dependents.remove(req);
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a capability from the internal data structures. This may cause
+     * other modules to become unresolved as a result.
+     * @param c the capability to remove.
+     * @param unresolvedRevisions a list to containing any additional modules that
+     *        that became unresolved as a result of removing this module and will
+     *        also need to be removed.
+     * @throws ResolveException if removing the module caused the resolve to fail.
+    **/
+    private void remove(Capability c, Set<Resource> unresolvedResources)
+        throws ResolutionException
+    {
+        Set<Requirement> dependents = m_dependentMap.remove(c);
+        if (dependents != null)
+        {
+            for (Requirement r : dependents)
+            {
+                List<Capability> candidates = m_candidateMap.get(r);
+                candidates.remove(c);
+                if (candidates.isEmpty())
+                {
+                    m_candidateMap.remove(r);
+                    if (!Util.isOptional(r))
+                    {
+                        String msg = "Unable to resolve " + r.getResource()
+                            + ": missing requirement " + r;
+                        m_populateResultCache.put(
+                            r.getResource(),
+                            new ResolutionException(msg, null, Collections.singleton(r)));
+                        unresolvedResources.add(r.getResource());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a copy of the Candidates object. This is used for creating
+     * permutations when package space conflicts are discovered.
+     * @return copy of this Candidates object.
+    **/
+    public Candidates copy()
+    {
+        Map<Capability, Set<Requirement>> dependentMap =
+            new HashMap<Capability, Set<Requirement>>();
+        for (Entry<Capability, Set<Requirement>> entry : m_dependentMap.entrySet())
+        {
+            Set<Requirement> dependents = new HashSet<Requirement>(entry.getValue());
+            dependentMap.put(entry.getKey(), dependents);
+        }
+
+        Map<Requirement, List<Capability>> candidateMap =
+            new HashMap<Requirement, List<Capability>>();
+        for (Entry<Requirement, List<Capability>> entry
+            : m_candidateMap.entrySet())
+        {
+            List<Capability> candidates =
+                new ArrayList<Capability>(entry.getValue());
+            candidateMap.put(entry.getKey(), candidates);
+        }
+
+        return new Candidates(
+            m_mandatoryResources, dependentMap, candidateMap,
+            m_allWrappedHosts, m_populateResultCache, m_fragmentsPresent);
+    }
+
+    public void dump(ResolveContext rc)
+    {
+        // Create set of all revisions from requirements.
+        Set<Resource> resources = new HashSet<Resource>();
+        for (Entry<Requirement, List<Capability>> entry
+            : m_candidateMap.entrySet())
+        {
+            resources.add(entry.getKey().getResource());
+        }
+        // Now dump the revisions.
+        System.out.println("=== BEGIN CANDIDATE MAP ===");
+        for (Resource resource : resources)
+        {
+            Wiring wiring = rc.getWirings().get(resource);
+            System.out.println("  " + resource
+                 + " (" + ((wiring != null) ? "RESOLVED)" : "UNRESOLVED)"));
+            List<Requirement> reqs = (wiring != null)
+                ? wiring.getResourceRequirements(null)
+                : resource.getRequirements(null);
+            for (Requirement req : reqs)
+            {
+                List<Capability> candidates = m_candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+            reqs = (wiring != null)
+                ? Util.getDynamicRequirements(wiring.getResourceRequirements(null))
+                : Util.getDynamicRequirements(resource.getRequirements(null));
+            for (Requirement req : reqs)
+            {
+                List<Capability> candidates = m_candidateMap.get(req);
+                if ((candidates != null) && (candidates.size() > 0))
+                {
+                    System.out.println("    " + req + ": " + candidates);
+                }
+            }
+        }
+        System.out.println("=== END CANDIDATE MAP ===");
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Logger.java b/resolver/src/main/java/org/apache/felix/resolver/Logger.java
new file mode 100644
index 0000000..9eaa212
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/Logger.java
@@ -0,0 +1,122 @@
+/*
+ * 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.resolver;
+
+/**
+ * <p>
+ * This class mimics the standard OSGi <tt>LogService</tt> interface. An
+ * instance of this class is used by the framework for all logging. By default
+ * this class logs messages to standard out. The log level can be set to
+ * control the amount of logging performed, where a higher number results in
+ * more logging. A log level of zero turns off logging completely.
+ * </p>
+ * <p>
+ * The log levels match those specified in the OSGi Log Service (i.e., 1 = error,
+ * 2 = warning, 3 = information, and 4 = debug). The default value is 1.
+ * </p>
+ * <p>
+ * This class also uses the System Bundle's context to track log services
+ * and will use the highest ranking log service, if present, as a back end
+ * instead of printing to standard out. The class uses reflection to invoking
+ * the log service's method to avoid a dependency on the log interface.
+ * </p>
+**/
+public class Logger
+{
+    public static final int LOG_ERROR = 1;
+    public static final int LOG_WARNING = 2;
+    public static final int LOG_INFO = 3;
+    public static final int LOG_DEBUG = 4;
+
+    private int m_logLevel = 1;
+
+    private final static int LOGGER_OBJECT_IDX = 0;
+    private final static int LOGGER_METHOD_IDX = 1;
+    private Object[] m_logger = null;
+
+    public Logger(int i)
+    {
+        m_logLevel = i;
+    }
+
+    public final synchronized void setLogLevel(int i)
+    {
+        m_logLevel = i;
+    }
+
+    public final synchronized int getLogLevel()
+    {
+        return m_logLevel;
+    }
+
+    public final void log(int level, String msg)
+    {
+        _log(level, msg, null);
+    }
+
+    public final void log(int level, String msg, Throwable throwable)
+    {
+        _log(level, msg, throwable);
+    }
+
+    protected void doLog(int level, String msg, Throwable throwable)
+    {
+        String s = "";
+        s = s + msg;
+        if (throwable != null)
+        {
+            s = s + " (" + throwable + ")";
+        }
+        switch (level)
+        {
+            case LOG_DEBUG:
+                System.out.println("DEBUG: " + s);
+                break;
+            case LOG_ERROR:
+                System.out.println("ERROR: " + s);
+                if (throwable != null)
+                {
+                    throwable.printStackTrace();
+                }
+                break;
+            case LOG_INFO:
+                System.out.println("INFO: " + s);
+                break;
+            case LOG_WARNING:
+                System.out.println("WARNING: " + s);
+                break;
+            default:
+                System.out.println("UNKNOWN[" + level + "]: " + s);
+        }
+    }
+
+    private void _log(
+        int level,
+        String msg, Throwable throwable)
+    {
+        // Save our own copy just in case it changes. We could try to do
+        // more conservative locking here, but let's be optimistic.
+        Object[] logger = m_logger;
+
+        if (m_logLevel >= level)
+        {
+            doLog(level, msg, throwable);
+        }
+    }
+}
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
new file mode 100644
index 0000000..e6d3311
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
@@ -0,0 +1,1830 @@
+/*
+ * 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.resolver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.resolver.ResolveContext;
+import org.osgi.service.resolver.Resolver;
+
+public class ResolverImpl implements Resolver
+{
+    private final Logger m_logger;
+
+    // Holds candidate permutations based on permutating "uses" chains.
+    // These permutations are given higher priority.
+    private final List<Candidates> m_usesPermutations = new ArrayList<Candidates>();
+    // Holds candidate permutations based on permutating requirement candidates.
+    // These permutations represent backtracking on previous decisions.
+    private final List<Candidates> m_importPermutations = new ArrayList<Candidates>();
+
+    public ResolverImpl(Logger logger)
+    {
+        m_logger = logger;
+    }
+
+    public Map<Resource, List<Wire>> resolve(ResolveContext rc) throws ResolutionException
+    {
+        Map<Resource, List<Wire>> wireMap =
+            new HashMap<Resource, List<Wire>>();
+        Map<Resource, Packages> resourcePkgMap =
+            new HashMap<Resource, Packages>();
+
+        Collection<Resource> mandatoryResources = rc.getMandatoryResources();
+        Collection<Resource> optionalResources = rc.getOptionalResources();
+// TODO: RFC-112 - Need impl-specific type.
+//        Collection<Resource> ondemandFragments = (rc instanceof ResolveContextImpl)
+//            ? ((ResolveContextImpl) rc).getOndemandResources() : Collections.EMPTY_LIST;
+        Collection<Resource> ondemandFragments =  Collections.EMPTY_LIST;
+
+        boolean retry;
+        do
+        {
+            retry = false;
+
+            try
+            {
+                // Create object to hold all candidates.
+                Candidates allCandidates = new Candidates();
+
+                // Populate mandatory resources; since these are mandatory
+                // resources, failure throws a resolve exception.
+                for (Iterator<Resource> it = mandatoryResources.iterator();
+                    it.hasNext(); )
+                {
+                    Resource resource = it.next();
+                    if (Util.isFragment(resource) || (rc.getWirings().get(resource) == null))
+                    {
+                        allCandidates.populate(rc, resource, Candidates.MANDATORY);
+                    }
+                    else
+                    {
+                        it.remove();
+                    }
+                }
+
+                // Populate optional resources; since these are optional
+                // resources, failure does not throw a resolve exception.
+                for (Resource resource : optionalResources)
+                {
+                    boolean isFragment = Util.isFragment(resource);
+                    if (isFragment || (rc.getWirings().get(resource) == null))
+                    {
+                        allCandidates.populate(rc, resource, Candidates.OPTIONAL);
+                    }
+                }
+
+                // Populate ondemand fragments; since these are optional
+                // resources, failure does not throw a resolve exception.
+                for (Resource resource : ondemandFragments)
+                {
+                    boolean isFragment = Util.isFragment(resource);
+                    if (isFragment)
+                    {
+                        allCandidates.populate(rc, resource, Candidates.ON_DEMAND);
+                    }
+                }
+
+                // Merge any fragments into hosts.
+                allCandidates.prepare(rc);
+
+                // Create a combined list of populated resources; for
+                // optional resources. We do not need to consider ondemand
+                // fragments, since they will only be pulled in if their
+                // host is already present.
+                Set<Resource> allResources =
+                    new HashSet<Resource>(mandatoryResources);
+                for (Resource resource : optionalResources)
+                {
+                    if (allCandidates.isPopulated(resource))
+                    {
+                        allResources.add(resource);
+                    }
+                }
+
+                // Record the initial candidate permutation.
+                m_usesPermutations.add(allCandidates);
+
+                ResolutionException rethrow = null;
+
+                // If a populated resource is a fragment, then its host
+                // must ultimately be verified, so store its host requirement
+                // to use for package space calculation.
+                Map<Resource, List<Requirement>> hostReqs =
+                    new HashMap<Resource, List<Requirement>>();
+                for (Resource resource : allResources)
+                {
+                    if (Util.isFragment(resource))
+                    {
+                        hostReqs.put(
+                            resource,
+                            resource.getRequirements(HostNamespace.HOST_NAMESPACE));
+                    }
+                }
+
+                do
+                {
+                    rethrow = null;
+
+                    resourcePkgMap.clear();
+                    m_packageSourcesCache.clear();
+
+                    allCandidates = (m_usesPermutations.size() > 0)
+                        ? m_usesPermutations.remove(0)
+                        : m_importPermutations.remove(0);
+//allCandidates.dump();
+
+                    for (Resource resource : allResources)
+                    {
+                        Resource target = resource;
+
+                        // If we are resolving a fragment, then get its
+                        // host candidate and verify it instead.
+                        List<Requirement> hostReq = hostReqs.get(resource);
+                        if (hostReq != null)
+                        {
+                            target = allCandidates.getCandidates(hostReq.get(0))
+                                .iterator().next().getResource();
+                        }
+
+                        calculatePackageSpaces(
+                            rc, allCandidates.getWrappedHost(target), allCandidates,
+                            resourcePkgMap, new HashMap(), new HashSet());
+//System.out.println("+++ PACKAGE SPACES START +++");
+//dumpResourcePkgMap(resourcePkgMap);
+//System.out.println("+++ PACKAGE SPACES END +++");
+
+                        try
+                        {
+                            checkPackageSpaceConsistency(
+                                rc, false, allCandidates.getWrappedHost(target),
+                                allCandidates, resourcePkgMap, new HashMap());
+                        }
+                        catch (ResolutionException ex)
+                        {
+                            rethrow = ex;
+                        }
+                    }
+                }
+                while ((rethrow != null)
+                    && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
+
+                // If there is a resolve exception, then determine if an
+                // optionally resolved resource is to blame (typically a fragment).
+                // If so, then remove the optionally resolved resolved and try
+                // again; otherwise, rethrow the resolve exception.
+                if (rethrow != null)
+                {
+                    Collection<Requirement> exReqs = rethrow.getUnresolvedRequirements();
+                    Requirement faultyReq = ((exReqs == null) || (exReqs.isEmpty()))
+                        ? null : exReqs.iterator().next();
+                    Resource faultyResource = (faultyReq == null)
+                        ? null : getDeclaredResource(faultyReq.getResource());
+                    // If the faulty requirement is wrapped, then it may
+                    // be from a fragment, so consider the fragment faulty
+                    // instead of the host.
+                    if (faultyReq instanceof WrappedRequirement)
+                    {
+                        faultyResource =
+                            ((WrappedRequirement) faultyReq)
+                                .getDeclaredRequirement().getResource();
+                    }
+                    // Try to ignore the faulty resource if it is not mandatory.
+                    if (optionalResources.remove(faultyResource))
+                    {
+                        retry = true;
+                    }
+                    else if (ondemandFragments.remove(faultyResource))
+                    {
+                        retry = true;
+                    }
+                    else
+                    {
+                        throw rethrow;
+                    }
+                }
+                // If there is no exception to rethrow, then this was a clean
+                // resolve, so populate the wire map.
+                else
+                {
+                    for (Resource resource : allResources)
+                    {
+                        Resource target = resource;
+
+                        // If we are resolving a fragment, then we
+                        // actually want to populate its host's wires.
+                        List<Requirement> hostReq = hostReqs.get(resource);
+                        if (hostReq != null)
+                        {
+                            target = allCandidates.getCandidates(hostReq.get(0))
+                                .iterator().next().getResource();
+                        }
+
+                        if (allCandidates.isPopulated(target))
+                        {
+                            wireMap =
+                                populateWireMap(
+                                    rc, allCandidates.getWrappedHost(target),
+                                    resourcePkgMap, wireMap, allCandidates);
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                // Always clear the state.
+                m_usesPermutations.clear();
+                m_importPermutations.clear();
+            }
+        }
+        while (retry);
+
+        return wireMap;
+    }
+
+/*
+ TODO: RFC-112 - Modify dynamic import handling to be like obr-resolver prototype.
+    public Map<Resource, List<Wire>> resolve(
+        ResolveContext rc, Resouce resource, String pkgName)
+    {
+        // We can only create a dynamic import if the following
+        // conditions are met:
+        // 1. The specified resource is resolved.
+        // 2. The package in question is not already imported.
+        // 3. The package in question is not accessible via require-bundle.
+        // 4. The package in question is not exported by the resource.
+        // 5. The package in question matches a dynamic import of the resource.
+        // The following call checks all of these conditions and returns
+        // the associated dynamic import and matching capabilities.
+        Candidates allCandidates =
+            getDynamicImportCandidates(rc, resource, pkgName);
+        if (allCandidates != null)
+        {
+            Collection<Resource> ondemandFragments = (rc instanceof ResolveContextImpl)
+                ? ((ResolveContextImpl) rc).getOndemandResources() : Collections.EMPTY_LIST;
+
+            Map<Resource, List<ResolverWire>> wireMap =
+                new HashMap<Resource, List<ResolverWire>>();
+            Map<Resource, Packages> resourcePkgMap =
+                new HashMap<Resource, Packages>();
+
+            boolean retry;
+            do
+            {
+                retry = false;
+
+                try
+                {
+                    // Try to populate optional fragments.
+                    for (Resource r : ondemandFragments)
+                    {
+                        if (Util.isFragment(r))
+                        {
+                            allCandidates.populate(rc, r, Candidates.ON_DEMAND);
+                        }
+                    }
+
+                    // Merge any fragments into hosts.
+                    allCandidates.prepare(rc);
+
+                    // Record the initial candidate permutation.
+                    m_usesPermutations.add(allCandidates);
+
+                    ResolveException rethrow = null;
+
+                    do
+                    {
+                        rethrow = null;
+
+                        resourcePkgMap.clear();
+                        m_packageSourcesCache.clear();
+
+                        allCandidates = (m_usesPermutations.size() > 0)
+                            ? m_usesPermutations.remove(0)
+                            : m_importPermutations.remove(0);
+//allCandidates.dump();
+
+                        // For a dynamic import, the instigating resource
+                        // will never be a fragment since fragments never
+                        // execute code, so we don't need to check for
+                        // this case like we do for a normal resolve.
+
+                        calculatePackageSpaces(
+                            allCandidates.getWrappedHost(resource), allCandidates, resourcePkgMap,
+                            new HashMap(), new HashSet());
+//System.out.println("+++ PACKAGE SPACES START +++");
+//dumpResourcePkgMap(resourcePkgMap);
+//System.out.println("+++ PACKAGE SPACES END +++");
+
+                        try
+                        {
+                            checkPackageSpaceConsistency(
+                                false, allCandidates.getWrappedHost(resource),
+                                allCandidates, resourcePkgMap, new HashMap());
+                        }
+                        catch (ResolveException ex)
+                        {
+                            rethrow = ex;
+                        }
+                    }
+                    while ((rethrow != null)
+                        && ((m_usesPermutations.size() > 0) || (m_importPermutations.size() > 0)));
+
+                    // If there is a resolve exception, then determine if an
+                    // optionally resolved resource is to blame (typically a fragment).
+                    // If so, then remove the optionally resolved resource and try
+                    // again; otherwise, rethrow the resolve exception.
+                    if (rethrow != null)
+                    {
+                        Resource faultyResource =
+                            getDeclaredResource(rethrow.getResource()));
+                        if (rethrow.getRequirement() instanceof WrappedRequirement)
+                        {
+                            faultyResource =
+                                ((WrappedRequirement) rethrow.getRequirement())
+                                    .getOriginalRequirement().getResource());
+                        }
+                        if (ondemandFragments.remove(faultyResource))
+                        {
+                            retry = true;
+                        }
+                        else
+                        {
+                            throw rethrow;
+                        }
+                    }
+                    // If there is no exception to rethrow, then this was a clean
+                    // resolve, so populate the wire map.
+                    else
+                    {
+                        wireMap = populateDynamicWireMap(
+                            resource, pkgName, resourcePkgMap, wireMap, allCandidates);
+                        return wireMap;
+                    }
+                }
+                finally
+                {
+                    // Always clear the state.
+                    m_usesPermutations.clear();
+                    m_importPermutations.clear();
+                }
+            }
+            while (retry);
+        }
+
+        return null;
+    }
+
+    private static Candidates getDynamicImportCandidates(
+        ResolveContext rc, Resource resource, String pkgName)
+    {
+        // Unresolved resources cannot dynamically import, nor can the default
+        // package be dynamically imported.
+        if ((resource.getWiring() == null) || pkgName.length() == 0)
+        {
+            return null;
+        }
+
+        // If the resource doesn't have dynamic imports, then just return
+        // immediately.
+        List<Requirement> dynamics =
+            Util.getDynamicRequirements(resource.getWiring().getRequirements(null));
+        if ((dynamics == null) || dynamics.isEmpty())
+        {
+            return null;
+        }
+
+        // If the resource exports this package, then we cannot
+        // attempt to dynamically import it.
+        for (Capability cap : resource.getWiring().getCapabilities(null))
+        {
+            if (cap.getNamespace().equals(Resource.PACKAGE_NAMESPACE)
+                && cap.getAttributes().get(Resource.PACKAGE_NAMESPACE).equals(pkgName))
+            {
+                return null;
+            }
+        }
+
+        // If this resource already imports or requires this package, then
+        // we cannot dynamically import it.
+        if (((WiringImpl) resource.getWiring()).hasPackageSource(pkgName))
+        {
+            return null;
+        }
+
+        // Determine if any providers of the package exist.
+        Map<String, Object> attrs = Collections.singletonMap(
+            PackageNamespace.PACKAGE_NAMESPACE, (Object) pkgName);
+        RequirementImpl req = new RequirementImpl(
+            resource,
+            PackageNamespace.PACKAGE_NAMESPACE,
+            Collections.EMPTY_MAP,
+            attrs);
+        List<Capability> candidates = rc.findProviders(req, false);
+
+        // Try to find a dynamic requirement that matches the capabilities.
+        RequirementImpl dynReq = null;
+        for (int dynIdx = 0;
+            (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
+            dynIdx++)
+        {
+            for (Iterator<Capability> itCand = candidates.iterator();
+                (dynReq == null) && itCand.hasNext(); )
+            {
+                Capability cap = itCand.next();
+                if (CapabilitySet.matches(
+                    (CapabilityImpl) cap,
+                    ((RequirementImpl) dynamics.get(dynIdx)).getFilter()))
+                {
+                    dynReq = (RequirementImpl) dynamics.get(dynIdx);
+                }
+            }
+        }
+
+        // If we found a matching dynamic requirement, then filter out
+        // any candidates that do not match it.
+        if (dynReq != null)
+        {
+            for (Iterator<Capability> itCand = candidates.iterator();
+                itCand.hasNext(); )
+            {
+                Capability cap = itCand.next();
+                if (!CapabilitySet.matches(
+                    (CapabilityImpl) cap, dynReq.getFilter()))
+                {
+                    itCand.remove();
+                }
+            }
+        }
+        else
+        {
+            candidates.clear();
+        }
+
+        Candidates allCandidates = null;
+
+        if (candidates.size() > 0)
+        {
+            allCandidates = new Candidates();
+            allCandidates.populateDynamic(rc, resource, dynReq, candidates);
+        }
+
+        return allCandidates;
+    }
+*/
+    private void calculatePackageSpaces(
+        ResolveContext rc,
+        Resource resource,
+        Candidates allCandidates,
+        Map<Resource, Packages> resourcePkgMap,
+        Map<Capability, List<Resource>> usesCycleMap,
+        Set<Resource> cycle)
+    {
+        if (cycle.contains(resource))
+        {
+            return;
+        }
+        cycle.add(resource);
+
+        // Create parallel arrays for requirement and proposed candidate
+        // capability or actual capability if resource is resolved or not.
+        List<Requirement> reqs = new ArrayList();
+        List<Capability> caps = new ArrayList();
+        boolean isDynamicImporting = false;
+        Wiring wiring = rc.getWirings().get(resource);
+        if (wiring != null)
+        {
+            // Use wires to get actual requirements and satisfying capabilities.
+            for (Wire wire : wiring.getRequiredResourceWires(null))
+            {
+                // Wrap the requirement as a hosted requirement if it comes
+                // from a fragment, since we will need to know the host. We
+                // also need to wrap if the requirement is a dynamic import,
+                // since that requirement will be shared with any other
+                // matching dynamic imports.
+                Requirement r = wire.getRequirement();
+                if (!r.getResource().equals(wire.getRequirer())
+                    || ((r.getDirectives()
+                        .get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE) != null)
+                    && r.getDirectives()
+                        .get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE)
+                            .equals(PackageNamespace.RESOLUTION_DYNAMIC)))
+                {
+                    r = new WrappedRequirement(wire.getRequirer(), r);
+                }
+                // 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();
+                if (!c.getResource().equals(wire.getProvider()))
+                {
+                    c = new WrappedCapability(wire.getProvider(), c);
+                }
+                reqs.add(r);
+                caps.add(c);
+            }
+
+            // Since the resource is resolved, it could be dynamically importing,
+            // so check to see if there are candidates for any of its dynamic
+            // imports.
+            for (Requirement req
+                : Util.getDynamicRequirements(wiring.getResourceRequirements(null)))
+            {
+                // Get the candidates for the current requirement.
+                List<Capability> candCaps = allCandidates.getCandidates(req);
+                // Optional requirements may not have any candidates.
+                if (candCaps == null)
+                {
+                    continue;
+                }
+
+                // Grab first (i.e., highest priority) candidate.
+                Capability cap = candCaps.get(0);
+                reqs.add(req);
+                caps.add(cap);
+                isDynamicImporting = true;
+                // Can only dynamically import one at a time, so break
+                // out of the loop after the first.
+                break;
+            }
+        }
+        else
+        {
+            for (Requirement req : resource.getRequirements(null))
+            {
+                String resolution = req.getDirectives()
+                    .get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+                if ((resolution == null)
+                    || !resolution.equals(PackageNamespace.RESOLUTION_DYNAMIC))
+                {
+                    // Get the candidates for the current requirement.
+                    List<Capability> candCaps = allCandidates.getCandidates(req);
+                    // Optional requirements may not have any candidates.
+                    if (candCaps == null)
+                    {
+                        continue;
+                    }
+
+                    // Grab first (i.e., highest priority) candidate.
+                    Capability cap = candCaps.get(0);
+                    reqs.add(req);
+                    caps.add(cap);
+                }
+            }
+        }
+
+        // First, add all exported packages to the target resource's package space.
+        calculateExportedPackages(rc, resource, allCandidates, resourcePkgMap);
+        Packages resourcePkgs = resourcePkgMap.get(resource);
+
+        // Second, add all imported packages to the target resource's package space.
+        for (int i = 0; i < reqs.size(); i++)
+        {
+            Requirement req = reqs.get(i);
+            Capability cap = caps.get(i);
+            calculateExportedPackages(rc, cap.getResource(), allCandidates, resourcePkgMap);
+            mergeCandidatePackages(
+                rc, resource, req, cap, resourcePkgMap, allCandidates,
+                new HashMap<Resource, List<Capability>>());
+        }
+
+        // Third, have all candidates to calculate their package spaces.
+        for (int i = 0; i < caps.size(); i++)
+        {
+            calculatePackageSpaces(
+                rc, caps.get(i).getResource(), allCandidates, resourcePkgMap,
+                usesCycleMap, cycle);
+        }
+
+        // Fourth, if the target resource is unresolved or is dynamically importing,
+        // then add all the uses constraints implied by its imported and required
+        // packages to its package space.
+        // NOTE: We do not need to do this for resolved resources because their
+        // package space is consistent by definition and these uses constraints
+        // are only needed to verify the consistency of a resolving resource. The
+        // only exception is if a resolved resource is dynamically importing, then
+        // we need to calculate its uses constraints again to make sure the new
+        // import is consistent with the existing package space.
+        if ((wiring == null) || isDynamicImporting)
+        {
+            // Merge uses constraints from required capabilities.
+            for (int i = 0; i < reqs.size(); i++)
+            {
+                Requirement req = reqs.get(i);
+                Capability cap = caps.get(i);
+                // Ignore bundle/package requirements, since they are
+                // considered below.
+                if (!req.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE)
+                    && !req.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                {
+                    List<Requirement> blameReqs = new ArrayList<Requirement>();
+                    blameReqs.add(req);
+
+                    mergeUses(
+                        rc,
+                        resource,
+                        resourcePkgs,
+                        cap,
+                        blameReqs,
+                        resourcePkgMap,
+                        allCandidates,
+                        usesCycleMap);
+                }
+            }
+            // Merge uses constraints from imported packages.
+            for (Entry<String, List<Blame>> entry : resourcePkgs.m_importedPkgs.entrySet())
+            {
+                for (Blame blame : entry.getValue())
+                {
+                    // Ignore resources that import from themselves.
+                    if (!blame.m_cap.getResource().equals(resource))
+                    {
+                        List<Requirement> blameReqs = new ArrayList();
+                        blameReqs.add(blame.m_reqs.get(0));
+
+                        mergeUses(
+                            rc,
+                            resource,
+                            resourcePkgs,
+                            blame.m_cap,
+                            blameReqs,
+                            resourcePkgMap,
+                            allCandidates,
+                            usesCycleMap);
+                    }
+                }
+            }
+            // Merge uses constraints from required bundles.
+            for (Entry<String, List<Blame>> entry : resourcePkgs.m_requiredPkgs.entrySet())
+            {
+                for (Blame blame : entry.getValue())
+                {
+                    List<Requirement> blameReqs = new ArrayList();
+                    blameReqs.add(blame.m_reqs.get(0));
+
+                    mergeUses(
+                        rc,
+                        resource,
+                        resourcePkgs,
+                        blame.m_cap,
+                        blameReqs,
+                        resourcePkgMap,
+                        allCandidates,
+                        usesCycleMap);
+                }
+            }
+        }
+    }
+
+    private void mergeCandidatePackages(
+        ResolveContext rc, Resource current, Requirement currentReq,
+        Capability candCap, Map<Resource, Packages> resourcePkgMap,
+        Candidates allCandidates, Map<Resource, List<Capability>> cycles)
+    {
+        List<Capability> cycleCaps = cycles.get(current);
+        if (cycleCaps == null)
+        {
+            cycleCaps = new ArrayList<Capability>();
+            cycles.put(current, cycleCaps);
+        }
+        if (cycleCaps.contains(candCap))
+        {
+            return;
+        }
+        cycleCaps.add(candCap);
+
+        if (candCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+        {
+            mergeCandidatePackage(
+                current, false, currentReq, candCap, resourcePkgMap);
+        }
+        else if (candCap.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE))
+        {
+// TODO: FELIX3 - THIS NEXT LINE IS A HACK. IMPROVE HOW/WHEN WE CALCULATE EXPORTS.
+            calculateExportedPackages(
+                rc, candCap.getResource(), allCandidates, resourcePkgMap);
+
+            // Get the candidate's package space to determine which packages
+            // will be visible to the current resource.
+            Packages candPkgs = resourcePkgMap.get(candCap.getResource());
+
+            // We have to merge all exported packages from the candidate,
+            // since the current resource requires it.
+            for (Entry<String, Blame> entry : candPkgs.m_exportedPkgs.entrySet())
+            {
+                mergeCandidatePackage(
+                    current,
+                    true,
+                    currentReq,
+                    entry.getValue().m_cap,
+                    resourcePkgMap);
+            }
+
+            // If the candidate requires any other bundles with reexport visibility,
+            // then we also need to merge their packages too.
+            Wiring candWiring = rc.getWirings().get(candCap.getResource());
+            if (candWiring != null)
+            {
+                for (Wire w : candWiring.getRequiredResourceWires(null))
+                {
+                    if (w.getRequirement().getNamespace()
+                        .equals(BundleNamespace.BUNDLE_NAMESPACE))
+                    {
+                        String value = w.getRequirement()
+                            .getDirectives()
+                                .get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
+                        if ((value != null)
+                            && value.equals(BundleNamespace.VISIBILITY_REEXPORT))
+                        {
+                            mergeCandidatePackages(
+                                rc,
+                                current,
+                                currentReq,
+                                w.getCapability(),
+                                resourcePkgMap,
+                                allCandidates,
+                                cycles);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                for (Requirement req : candCap.getResource().getRequirements(null))
+                {
+                    if (req.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE))
+                    {
+                        String value =
+                            req.getDirectives()
+                                .get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
+                        if ((value != null)
+                            && value.equals(BundleNamespace.VISIBILITY_REEXPORT)
+                            && (allCandidates.getCandidates(req) != null))
+                        {
+                            mergeCandidatePackages(
+                                rc,
+                                current,
+                                currentReq,
+                                allCandidates.getCandidates(req).iterator().next(),
+                                resourcePkgMap,
+                                allCandidates,
+                                cycles);
+                        }
+                    }
+                }
+            }
+        }
+
+        cycles.remove(current);
+    }
+
+    private void mergeCandidatePackage(
+        Resource current, boolean requires,
+        Requirement currentReq, Capability candCap,
+        Map<Resource, Packages> resourcePkgMap)
+    {
+        if (candCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+        {
+            // Merge the candidate capability into the resource's package space
+            // for imported or required packages, appropriately.
+
+            String pkgName = (String)
+                candCap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+
+            List blameReqs = new ArrayList();
+            blameReqs.add(currentReq);
+
+            Packages currentPkgs = resourcePkgMap.get(current);
+
+            Map<String, List<Blame>> packages = (requires)
+                ? currentPkgs.m_requiredPkgs
+                : currentPkgs.m_importedPkgs;
+            List<Blame> blames = packages.get(pkgName);
+            if (blames == null)
+            {
+                blames = new ArrayList<Blame>();
+                packages.put(pkgName, blames);
+            }
+            blames.add(new Blame(candCap, blameReqs));
+
+//dumpResourcePkgs(current, currentPkgs);
+        }
+    }
+
+    private void mergeUses(
+        ResolveContext rc, Resource current, Packages currentPkgs,
+        Capability mergeCap, List<Requirement> blameReqs,
+        Map<Resource, Packages> resourcePkgMap,
+        Candidates allCandidates,
+        Map<Capability, List<Resource>> cycleMap)
+    {
+        // If there are no uses, then just return.
+        // If the candidate resource is the same as the current resource,
+        // then we don't need to verify and merge the uses constraints
+        // since this will happen as we build up the package space.
+        if (current.equals(mergeCap.getResource()))
+        {
+            return;
+        }
+
+        // Check for cycles.
+        List<Resource> list = cycleMap.get(mergeCap);
+        if ((list != null) && list.contains(current))
+        {
+            return;
+        }
+        list = (list == null) ? new ArrayList<Resource>() : list;
+        list.add(current);
+        cycleMap.put(mergeCap, list);
+
+        for (Capability candSourceCap : getPackageSources(rc, mergeCap, resourcePkgMap))
+        {
+            List<String> uses;
+// TODO: RFC-112 - Need impl-specific type
+//            if (candSourceCap instanceof FelixCapability)
+//            {
+//                uses = ((FelixCapability) candSourceCap).getUses();
+//            }
+//            else
+            {
+                uses = Collections.EMPTY_LIST;
+                String s = candSourceCap.getDirectives()
+                    .get(Namespace.CAPABILITY_USES_DIRECTIVE);
+                if (s != null)
+                {
+                    // Parse these uses directive.
+                    StringTokenizer tok = new StringTokenizer(s, ",");
+                    uses = new ArrayList(tok.countTokens());
+                    while (tok.hasMoreTokens())
+                    {
+                        uses.add(tok.nextToken().trim());
+                    }
+                }
+            }
+            for (String usedPkgName : uses)
+            {
+                Packages candSourcePkgs = resourcePkgMap.get(candSourceCap.getResource());
+                List<Blame> candSourceBlames = null;
+                // Check to see if the used package is exported.
+                Blame candExportedBlame = candSourcePkgs.m_exportedPkgs.get(usedPkgName);
+                if (candExportedBlame != null)
+                {
+                    candSourceBlames = new ArrayList(1);
+                    candSourceBlames.add(candExportedBlame);
+                }
+                else
+                {
+                    // If the used package is not exported, check to see if it
+                    // is required.
+                    candSourceBlames = candSourcePkgs.m_requiredPkgs.get(usedPkgName);
+                    // Lastly, if the used package is not required, check to see if it
+                    // is imported.
+                    candSourceBlames = (candSourceBlames != null)
+                        ? candSourceBlames : candSourcePkgs.m_importedPkgs.get(usedPkgName);
+                }
+
+                // If the used package cannot be found, then just ignore it
+                // since it has no impact.
+                if (candSourceBlames == null)
+                {
+                    continue;
+                }
+
+                List<Blame> usedCaps = currentPkgs.m_usedPkgs.get(usedPkgName);
+                if (usedCaps == null)
+                {
+                    usedCaps = new ArrayList<Blame>();
+                    currentPkgs.m_usedPkgs.put(usedPkgName, usedCaps);
+                }
+                for (Blame blame : candSourceBlames)
+                {
+                    if (blame.m_reqs != null)
+                    {
+                        List<Requirement> blameReqs2 = new ArrayList(blameReqs);
+                        blameReqs2.add(blame.m_reqs.get(blame.m_reqs.size() - 1));
+                        usedCaps.add(new Blame(blame.m_cap, blameReqs2));
+                        mergeUses(rc, current, currentPkgs, blame.m_cap, blameReqs2,
+                            resourcePkgMap, allCandidates, cycleMap);
+                    }
+                    else
+                    {
+                        usedCaps.add(new Blame(blame.m_cap, blameReqs));
+                        mergeUses(rc, current, currentPkgs, blame.m_cap, blameReqs,
+                            resourcePkgMap, allCandidates, cycleMap);
+                    }
+                }
+            }
+        }
+    }
+
+    private void checkPackageSpaceConsistency(
+        ResolveContext rc,
+        boolean isDynamicImporting,
+        Resource resource,
+        Candidates allCandidates,
+        Map<Resource, Packages> resourcePkgMap,
+        Map<Resource, Object> resultCache) throws ResolutionException
+    {
+        if (rc.getWirings().containsKey(resource) && !isDynamicImporting)
+        {
+            return;
+        }
+        else if(resultCache.containsKey(resource))
+        {
+            return;
+        }
+
+        Packages pkgs = resourcePkgMap.get(resource);
+
+        ResolutionException rethrow = null;
+        Candidates permutation = null;
+        Set<Requirement> mutated = null;
+
+        // Check for conflicting imports from fragments.
+        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
+        {
+            if (entry.getValue().size() > 1)
+            {
+                Blame sourceBlame = null;
+                for (Blame blame : entry.getValue())
+                {
+                    if (sourceBlame == null)
+                    {
+                        sourceBlame = blame;
+                    }
+                    else if (!sourceBlame.m_cap.getResource().equals(blame.m_cap.getResource()))
+                    {
+                        // Try to permutate the conflicting requirement.
+                        permutate(allCandidates, blame.m_reqs.get(0), m_importPermutations);
+                        // Try to permutate the source requirement.
+                        permutate(allCandidates, sourceBlame.m_reqs.get(0), m_importPermutations);
+                        // Report conflict.
+                        ResolutionException ex = new ResolutionException(
+                            "Uses constraint violation. Unable to resolve resource "
+                            + Util.getSymbolicName(resource)
+                            + " [" + resource
+                            + "] because it is exposed to package '"
+                            + entry.getKey()
+                            + "' from resources "
+                            + Util.getSymbolicName(sourceBlame.m_cap.getResource())
+                            + " [" + sourceBlame.m_cap.getResource()
+                            + "] and "
+                            + Util.getSymbolicName(blame.m_cap.getResource())
+                            + " [" + blame.m_cap.getResource()
+                            + "] via two dependency chains.\n\nChain 1:\n"
+                            + toStringBlame(rc, allCandidates, sourceBlame)
+                            + "\n\nChain 2:\n"
+                            + toStringBlame(rc, allCandidates, blame),
+                            null,
+                            Collections.singleton(blame.m_reqs.get(0)));
+                        m_logger.log(
+                            Logger.LOG_DEBUG,
+                            "Candidate permutation failed due to a conflict with a "
+                            + "fragment import; will try another if possible.",
+                            ex);
+                        throw ex;
+                    }
+                }
+            }
+        }
+
+        // Check if there are any uses conflicts with exported packages.
+        for (Entry<String, Blame> entry : pkgs.m_exportedPkgs.entrySet())
+        {
+            String pkgName = entry.getKey();
+            Blame exportBlame = entry.getValue();
+            if (!pkgs.m_usedPkgs.containsKey(pkgName))
+            {
+                continue;
+            }
+            for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
+            {
+                if (!isCompatible(rc, exportBlame.m_cap, usedBlame.m_cap, resourcePkgMap))
+                {
+                    // Create a candidate permutation that eliminates all candidates
+                    // that conflict with existing selected candidates.
+                    permutation = (permutation != null)
+                        ? permutation
+                        : allCandidates.copy();
+                    rethrow = (rethrow != null)
+                        ? rethrow
+                        : new ResolutionException(
+                            "Uses constraint violation. Unable to resolve resource "
+                            + Util.getSymbolicName(resource)
+                            + " [" + resource
+                            + "] because it exports package '"
+                            + pkgName
+                            + "' and is also exposed to it from resource "
+                            + Util.getSymbolicName(usedBlame.m_cap.getResource())
+                            + " [" + usedBlame.m_cap.getResource()
+                            + "] via the following dependency chain:\n\n"
+                            + toStringBlame(rc, allCandidates, usedBlame),
+                            null,
+                            null);
+
+                    mutated = (mutated != null)
+                        ? mutated
+                        : new HashSet<Requirement>();
+
+                    for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
+                    {
+                        Requirement req = usedBlame.m_reqs.get(reqIdx);
+
+                        // If we've already permutated this requirement in another
+                        // uses constraint, don't permutate it again just continue
+                        // with the next uses constraint.
+                        if (mutated.contains(req))
+                        {
+                            break;
+                        }
+
+                        // See if we can permutate the candidates for blamed
+                        // requirement; there may be no candidates if the resource
+                        // associated with the requirement is already resolved.
+                        List<Capability> candidates = permutation.getCandidates(req);
+                        if ((candidates != null) && (candidates.size() > 1))
+                        {
+                            mutated.add(req);
+                            // Remove the conflicting candidate.
+                            candidates.remove(0);
+                            // Continue with the next uses constraint.
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (rethrow != null)
+            {
+                if (mutated.size() > 0)
+                {
+                    m_usesPermutations.add(permutation);
+                }
+                m_logger.log(
+                    Logger.LOG_DEBUG,
+                    "Candidate permutation failed due to a conflict between "
+                    + "an export and import; will try another if possible.",
+                    rethrow);
+                throw rethrow;
+            }
+        }
+
+        // Check if there are any uses conflicts with imported packages.
+        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
+        {
+            for (Blame importBlame : entry.getValue())
+            {
+                String pkgName = entry.getKey();
+                if (!pkgs.m_usedPkgs.containsKey(pkgName))
+                {
+                    continue;
+                }
+                for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
+                {
+                    if (!isCompatible(rc, importBlame.m_cap, usedBlame.m_cap, resourcePkgMap))
+                    {
+                        // Create a candidate permutation that eliminates any candidates
+                        // that conflict with existing selected candidates.
+                        permutation = (permutation != null)
+                            ? permutation
+                            : allCandidates.copy();
+                        rethrow = (rethrow != null)
+                            ? rethrow
+                            : new ResolutionException(
+                                "Uses constraint violation. Unable to resolve resource "
+                                + Util.getSymbolicName(resource)
+                                + " [" + resource
+                                + "] because it is exposed to package '"
+                                + pkgName
+                                + "' from resources "
+                                + Util.getSymbolicName(importBlame.m_cap.getResource())
+                                + " [" + importBlame.m_cap.getResource()
+                                + "] and "
+                                + Util.getSymbolicName(usedBlame.m_cap.getResource())
+                                + " [" + usedBlame.m_cap.getResource()
+                                + "] via two dependency chains.\n\nChain 1:\n"
+                                + toStringBlame(rc, allCandidates, importBlame)
+                                + "\n\nChain 2:\n"
+                                + toStringBlame(rc, allCandidates, usedBlame),
+                                null,
+                                null);
+
+                        mutated = (mutated != null)
+                            ? mutated
+                            : new HashSet();
+
+                        for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
+                        {
+                            Requirement req = usedBlame.m_reqs.get(reqIdx);
+
+                            // If we've already permutated this requirement in another
+                            // uses constraint, don't permutate it again just continue
+                            // with the next uses constraint.
+                            if (mutated.contains(req))
+                            {
+                                break;
+                            }
+
+                            // See if we can permutate the candidates for blamed
+                            // requirement; there may be no candidates if the resource
+                            // associated with the requirement is already resolved.
+                            List<Capability> candidates = permutation.getCandidates(req);
+                            if ((candidates != null) && (candidates.size() > 1))
+                            {
+                                mutated.add(req);
+                                // Remove the conflicting candidate.
+                                candidates.remove(0);
+                                // Continue with the next uses constraint.
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                // If there was a uses conflict, then we should add a uses
+                // permutation if we were able to permutate any candidates.
+                // Additionally, we should try to push an import permutation
+                // for the original import to force a backtracking on the
+                // original candidate decision if no viable candidate is found
+                // for the conflicting uses constraint.
+                if (rethrow != null)
+                {
+                    // Add uses permutation if we mutated any candidates.
+                    if (mutated.size() > 0)
+                    {
+                        m_usesPermutations.add(permutation);
+                    }
+
+                    // 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);
+                    if (!mutated.contains(req))
+                    {
+                        // Since there may be lots of uses constraint violations
+                        // with existing import decisions, we may end up trying
+                        // to permutate the same import a lot of times, so we should
+                        // try to check if that the case and only permutate it once.
+                        permutateIfNeeded(allCandidates, req, m_importPermutations);
+                    }
+
+                    m_logger.log(
+                        Logger.LOG_DEBUG,
+                        "Candidate permutation failed due to a conflict between "
+                        + "imports; will try another if possible.",
+                        rethrow);
+                    throw rethrow;
+                }
+            }
+        }
+
+        resultCache.put(resource, Boolean.TRUE);
+
+        // Now check the consistency of all resources on which the
+        // current resource depends. Keep track of the current number
+        // of permutations so we know if the lower level check was
+        // able to create a permutation or not in the case of failure.
+        int permCount = m_usesPermutations.size() + m_importPermutations.size();
+        for (Entry<String, List<Blame>> entry : pkgs.m_importedPkgs.entrySet())
+        {
+            for (Blame importBlame : entry.getValue())
+            {
+                if (!resource.equals(importBlame.m_cap.getResource()))
+                {
+                    try
+                    {
+                        checkPackageSpaceConsistency(
+                            rc, false, importBlame.m_cap.getResource(),
+                            allCandidates, resourcePkgMap, resultCache);
+                    }
+                    catch (ResolutionException ex)
+                    {
+                        // If the lower level check didn't create any permutations,
+                        // then we should create an import permutation for the
+                        // requirement with the dependency on the failing resource
+                        // to backtrack on our current candidate selection.
+                        if (permCount == (m_usesPermutations.size() + m_importPermutations.size()))
+                        {
+                            Requirement req = importBlame.m_reqs.get(0);
+                            permutate(allCandidates, req, m_importPermutations);
+                        }
+                        throw ex;
+                    }
+                }
+            }
+        }
+    }
+
+    private static void permutate(
+        Candidates allCandidates, Requirement req, List<Candidates> permutations)
+    {
+        List<Capability> candidates = allCandidates.getCandidates(req);
+        if (candidates.size() > 1)
+        {
+            Candidates perm = allCandidates.copy();
+            candidates = perm.getCandidates(req);
+            candidates.remove(0);
+            permutations.add(perm);
+        }
+    }
+
+    private static void permutateIfNeeded(
+        Candidates allCandidates, Requirement req, List<Candidates> permutations)
+    {
+        List<Capability> candidates = allCandidates.getCandidates(req);
+        if (candidates.size() > 1)
+        {
+            // Check existing permutations to make sure we haven't
+            // already permutated this requirement. This check for
+            // duplicate permutations is simplistic. It assumes if
+            // there is any permutation that contains a different
+            // initial candidate for the requirement in question,
+            // then it has already been permutated.
+            boolean permutated = false;
+            for (Candidates existingPerm : permutations)
+            {
+                List<Capability> existingPermCands = existingPerm.getCandidates(req);
+                if (!existingPermCands.get(0).equals(candidates.get(0)))
+                {
+                    permutated = true;
+                }
+            }
+            // If we haven't already permutated the existing
+            // import, do so now.
+            if (!permutated)
+            {
+                permutate(allCandidates, req, permutations);
+            }
+        }
+    }
+
+    private static void calculateExportedPackages(
+        ResolveContext rc,
+        Resource resource,
+        Candidates allCandidates,
+        Map<Resource, Packages> resourcePkgMap)
+    {
+        Packages packages = resourcePkgMap.get(resource);
+        if (packages != null)
+        {
+            return;
+        }
+        packages = new Packages(resource);
+
+        // Get all exported packages.
+        Wiring wiring = rc.getWirings().get(resource);
+        List<Capability> caps = (wiring != null)
+            ? wiring.getResourceCapabilities(null)
+            : resource.getCapabilities(null);
+        Map<String, Capability> exports = new HashMap<String, Capability>(caps.size());
+        for (Capability cap : caps)
+        {
+            if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+            {
+                if (!cap.getResource().equals(resource))
+                {
+                    cap = new WrappedCapability(resource, cap);
+                }
+                exports.put(
+                    (String) cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE),
+                    cap);
+            }
+        }
+        // Remove substitutable exports that were imported.
+        // For resolved resources Wiring.getCapabilities()
+        // already excludes imported substitutable exports, but
+        // for resolving resources we must look in the candidate
+        // map to determine which exports are substitutable.
+        if (!exports.isEmpty())
+        {
+            if (wiring == null)
+            {
+                for (Requirement req : resource.getRequirements(null))
+                {
+                    if (req.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                    {
+                        List<Capability> cands = allCandidates.getCandidates(req);
+                        if ((cands != null) && !cands.isEmpty())
+                        {
+                            String pkgName = (String) cands.get(0)
+                                .getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+                            exports.remove(pkgName);
+                        }
+                    }
+                }
+            }
+
+            // Add all non-substituted exports to the resources's package space.
+            for (Entry<String, Capability> entry : exports.entrySet())
+            {
+                packages.m_exportedPkgs.put(
+                    entry.getKey(), new Blame(entry.getValue(), null));
+            }
+        }
+
+        resourcePkgMap.put(resource, packages);
+    }
+
+    private boolean isCompatible(
+        ResolveContext rc, Capability currentCap, Capability candCap,
+        Map<Resource, Packages> resourcePkgMap)
+    {
+        if ((currentCap != null) && (candCap != null))
+        {
+            if (currentCap.equals(candCap))
+            {
+                return true;
+            }
+
+            List<Capability> currentSources =
+                getPackageSources(
+                    rc,
+                    currentCap,
+                    resourcePkgMap);
+            List<Capability> candSources =
+                getPackageSources(
+                    rc,
+                    candCap,
+                    resourcePkgMap);
+
+            return currentSources.containsAll(candSources)
+                || candSources.containsAll(currentSources);
+        }
+        return true;
+    }
+
+    private Map<Capability, List<Capability>> m_packageSourcesCache = new HashMap();
+
+    private List<Capability> getPackageSources(
+        ResolveContext rc, Capability cap, Map<Resource, Packages> resourcePkgMap)
+    {
+        // If it is a package, then calculate sources for it.
+        if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+        {
+            List<Capability> sources = m_packageSourcesCache.get(cap);
+            if (sources == null)
+            {
+                sources = getPackageSourcesInternal(
+                    rc, cap, resourcePkgMap, new ArrayList(), new HashSet());
+                m_packageSourcesCache.put(cap, sources);
+            }
+            return sources;
+        }
+
+        // Otherwise, need to return generic capabilies that have
+        // uses constraints so they are included for consistency
+        // checking.
+        String uses = cap.getDirectives().get(Namespace.CAPABILITY_USES_DIRECTIVE);
+        if ((uses != null) && (uses.length() > 0))
+        {
+            return Collections.singletonList(cap);
+        }
+
+        return Collections.EMPTY_LIST;
+    }
+
+    private static List<Capability> getPackageSourcesInternal(
+        ResolveContext rc, Capability cap, Map<Resource, Packages> resourcePkgMap,
+        List<Capability> sources, Set<Capability> cycleMap)
+    {
+        if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+        {
+            if (cycleMap.contains(cap))
+            {
+                return sources;
+            }
+            cycleMap.add(cap);
+
+            // Get the package name associated with the capability.
+            String pkgName = cap.getAttributes()
+                .get(PackageNamespace.PACKAGE_NAMESPACE).toString();
+
+            // Since a resource can export the same package more than once, get
+            // all package capabilities for the specified package name.
+            Wiring wiring = rc.getWirings().get(cap.getResource());
+            List<Capability> caps = (wiring != null)
+                ? wiring.getResourceCapabilities(null)
+                : cap.getResource().getCapabilities(null);
+            for (Capability sourceCap : caps)
+            {
+                if (sourceCap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE)
+                    && sourceCap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE).equals(pkgName))
+                {
+                    // Since capabilities may come from fragments, we need to check
+                    // for that case and wrap them.
+                    if (!cap.getResource().equals(sourceCap.getResource()))
+                    {
+                        sources.add(new WrappedCapability(cap.getResource(), sourceCap));
+                    }
+                    else
+                    {
+                        sources.add(sourceCap);
+                    }
+                }
+            }
+
+            // Then get any addition sources for the package from required bundles.
+            Packages pkgs = resourcePkgMap.get(cap.getResource());
+            List<Blame> required = pkgs.m_requiredPkgs.get(pkgName);
+            if (required != null)
+            {
+                for (Blame blame : required)
+                {
+                    getPackageSourcesInternal(rc, blame.m_cap, resourcePkgMap, sources, cycleMap);
+                }
+            }
+        }
+
+        return sources;
+    }
+
+    private static Resource getDeclaredResource(Resource resource)
+    {
+        if (resource instanceof WrappedResource)
+        {
+            return ((WrappedResource) resource).getDeclaredResource();
+        }
+        return resource;
+    }
+
+    private static Capability getDeclaredCapability(Capability c)
+    {
+        if (c instanceof HostedCapability)
+        {
+            return ((HostedCapability) c).getDeclaredCapability();
+        }
+        return c;
+    }
+
+    private static Requirement getDeclaredRequirement(Requirement r)
+    {
+        if (r instanceof WrappedRequirement)
+        {
+            return ((WrappedRequirement) r).getDeclaredRequirement();
+        }
+        return r;
+    }
+
+    private static Map<Resource, List<Wire>> populateWireMap(
+        ResolveContext rc, Resource resource, Map<Resource, Packages> resourcePkgMap,
+        Map<Resource, List<Wire>> wireMap, Candidates allCandidates)
+    {
+        Resource unwrappedResource = getDeclaredResource(resource);
+        if (!rc.getWirings().containsKey(unwrappedResource)
+            && !wireMap.containsKey(unwrappedResource))
+        {
+            wireMap.put(unwrappedResource, (List<Wire>) Collections.EMPTY_LIST);
+
+            List<Wire> packageWires = new ArrayList<Wire>();
+            List<Wire> bundleWires = new ArrayList<Wire>();
+            List<Wire> capabilityWires = new ArrayList<Wire>();
+
+            for (Requirement req : resource.getRequirements(null))
+            {
+                List<Capability> cands = allCandidates.getCandidates(req);
+                if ((cands != null) && (cands.size() > 0))
+                {
+                    Capability cand = cands.get(0);
+                    // Ignore resources that import themselves.
+                    if (!resource.equals(cand.getResource()))
+                    {
+                        if (!rc.getWirings().containsKey(cand.getResource()))
+                        {
+                            populateWireMap(rc, cand.getResource(),
+                                resourcePkgMap, wireMap, allCandidates);
+                        }
+                        Packages candPkgs = resourcePkgMap.get(cand.getResource());
+                        Wire wire = new WireImpl(
+                            unwrappedResource,
+                            getDeclaredRequirement(req),
+                            getDeclaredResource(cand.getResource()),
+                            getDeclaredCapability(cand));
+                        if (req.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                        {
+                            packageWires.add(wire);
+                        }
+                        else if (req.getNamespace().equals(BundleNamespace.BUNDLE_NAMESPACE))
+                        {
+                            bundleWires.add(wire);
+                        }
+                        else
+                        {
+                            capabilityWires.add(wire);
+                        }
+                    }
+                }
+            }
+
+            // Combine package wires with require wires last.
+            packageWires.addAll(bundleWires);
+            packageWires.addAll(capabilityWires);
+            wireMap.put(unwrappedResource, packageWires);
+
+            // Add host wire for any fragments.
+            if (resource instanceof WrappedResource)
+            {
+                List<Resource> fragments = ((WrappedResource) resource).getFragments();
+                for (Resource fragment : fragments)
+                {
+                    List<Wire> hostWires = wireMap.get(fragment);
+                    if (hostWires == null)
+                    {
+                        hostWires = new ArrayList<Wire>();
+                        wireMap.put(fragment, hostWires);
+                    }
+                    hostWires.add(
+                        new WireImpl(
+                            getDeclaredResource(fragment),
+                            fragment.getRequirements(
+                                HostNamespace.HOST_NAMESPACE).get(0),
+                            unwrappedResource,
+                            unwrappedResource.getCapabilities(
+                                HostNamespace.HOST_NAMESPACE).get(0)));
+                }
+            }
+        }
+
+        return wireMap;
+    }
+
+    private static Map<Resource, List<Wire>> populateDynamicWireMap(
+        ResolveContext rc, Resource resource, Requirement dynReq,
+        Map<Resource, Packages> resourcePkgMap,
+        Map<Resource, List<Wire>> wireMap, Candidates allCandidates)
+    {
+        wireMap.put(resource, (List<Wire>) Collections.EMPTY_LIST);
+
+        List<Wire> packageWires = new ArrayList<Wire>();
+
+        // Get the candidates for the current dynamic requirement.
+        List<Capability> candCaps = allCandidates.getCandidates(dynReq);
+        // Record the dynamic candidate.
+        Capability dynCand = candCaps.get(0);
+
+        if (!rc.getWirings().containsKey(dynCand.getResource()))
+        {
+            populateWireMap(rc, dynCand.getResource(), resourcePkgMap,
+                wireMap, allCandidates);
+        }
+
+        packageWires.add(
+            new WireImpl(
+                resource,
+                dynReq,
+                getDeclaredResource(dynCand.getResource()),
+                getDeclaredCapability(dynCand)));
+
+        wireMap.put(resource, packageWires);
+
+        return wireMap;
+    }
+
+    private static void dumpResourcePkgMap(
+        ResolveContext rc, Map<Resource, Packages> resourcePkgMap)
+    {
+        System.out.println("+++RESOURCE PKG MAP+++");
+        for (Entry<Resource, Packages> entry : resourcePkgMap.entrySet())
+        {
+            dumpResourcePkgs(rc, entry.getKey(), entry.getValue());
+        }
+    }
+
+    private static void dumpResourcePkgs(
+        ResolveContext rc, Resource resource, Packages packages)
+    {
+        Wiring wiring = rc.getWirings().get(resource);
+        System.out.println(resource
+            + " (" + ((wiring != null) ? "RESOLVED)" : "UNRESOLVED)"));
+        System.out.println("  EXPORTED");
+        for (Entry<String, Blame> entry : packages.m_exportedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  IMPORTED");
+        for (Entry<String, List<Blame>> entry : packages.m_importedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  REQUIRED");
+        for (Entry<String, List<Blame>> entry : packages.m_requiredPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+        System.out.println("  USED");
+        for (Entry<String, List<Blame>> entry : packages.m_usedPkgs.entrySet())
+        {
+            System.out.println("    " + entry.getKey() + " - " + entry.getValue());
+        }
+    }
+
+    private static String toStringBlame(
+        ResolveContext rc, Candidates allCandidates, Blame blame)
+    {
+        StringBuffer sb = new StringBuffer();
+        if ((blame.m_reqs != null) && !blame.m_reqs.isEmpty())
+        {
+            for (int i = 0; i < blame.m_reqs.size(); i++)
+            {
+                Requirement req = blame.m_reqs.get(i);
+                sb.append("  ");
+                sb.append(Util.getSymbolicName(req.getResource()));
+                sb.append(" [");
+                sb.append(req.getResource().toString());
+                sb.append("]\n");
+                if (req.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                {
+                    sb.append("    import: ");
+                }
+                else
+                {
+                    sb.append("    require: ");
+                }
+                sb.append(req.getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE));
+                sb.append("\n     |");
+                if (req.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                {
+                    sb.append("\n    export: ");
+                }
+                else
+                {
+                    sb.append("\n    provide: ");
+                }
+                if ((i + 1) < blame.m_reqs.size())
+                {
+                    Capability cap = getSatisfyingCapability(
+                        rc,
+                        allCandidates,
+                        blame.m_reqs.get(i));
+                    if (cap.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+                    {
+                        sb.append(PackageNamespace.PACKAGE_NAMESPACE);
+                        sb.append("=");
+                        sb.append(cap.getAttributes()
+                            .get(PackageNamespace.PACKAGE_NAMESPACE).toString());
+                        Capability usedCap =
+                            getSatisfyingCapability(
+                                rc,
+                                allCandidates,
+                                blame.m_reqs.get(i + 1));
+                        sb.append("; uses:=");
+                        sb.append(usedCap.getAttributes()
+                            .get(PackageNamespace.PACKAGE_NAMESPACE));
+                    }
+                    else
+                    {
+                        sb.append(cap);
+                    }
+                    sb.append("\n");
+                }
+                else
+                {
+                    Capability export = getSatisfyingCapability(
+                        rc,
+                        allCandidates,
+                        blame.m_reqs.get(i));
+                    sb.append(export.getNamespace());
+                    sb.append("=");
+                    sb.append(export.getAttributes().get(export.getNamespace()).toString());
+                    if (export.getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE)
+                        && !export.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE)
+                            .equals(blame.m_cap.getAttributes().get(
+                                PackageNamespace.PACKAGE_NAMESPACE)))
+                    {
+                        sb.append("; uses:=");
+                        sb.append(blame.m_cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
+                        sb.append("\n    export: ");
+                        sb.append(PackageNamespace.PACKAGE_NAMESPACE);
+                        sb.append("=");
+                        sb.append(blame.m_cap.getAttributes()
+                            .get(PackageNamespace.PACKAGE_NAMESPACE).toString());
+                    }
+                    sb.append("\n  ");
+                    sb.append(Util.getSymbolicName(blame.m_cap.getResource()));
+                    sb.append(" [");
+                    sb.append(blame.m_cap.getResource().toString());
+                    sb.append("]");
+                }
+            }
+        }
+        else
+        {
+            sb.append(blame.m_cap.getResource().toString());
+        }
+        return sb.toString();
+    }
+
+    private static Capability getSatisfyingCapability(
+        ResolveContext rc, Candidates allCandidates, Requirement req)
+    {
+        Capability cap = null;
+
+        // If the requiring revision is not resolved, then check in the
+        // candidate map for its matching candidate.
+        List<Capability> cands = allCandidates.getCandidates(req);
+        if (cands != null)
+        {
+            cap = cands.get(0);
+        }
+        // Otherwise, if the requiring revision is resolved then check
+        // in its wires for the capability satisfying the requirement.
+        else if (rc.getWirings().containsKey(req.getResource()))
+        {
+            List<Wire> wires =
+                rc.getWirings().get(req.getResource()).getRequiredResourceWires(null);
+            req = getDeclaredRequirement(req);
+            for (Wire w : wires)
+            {
+                if (w.getRequirement().equals(req))
+                {
+// TODO: RESOLVER - This is not 100% correct, since requirements for
+//       dynamic imports with wildcards will reside on many wires and
+//       this code only finds the first one, not necessarily the correct
+//       one. This is only used for the diagnostic message, but it still
+//       could confuse the user.
+                    cap = w.getCapability();
+                    break;
+                }
+            }
+        }
+
+        return cap;
+    }
+
+    private static class Packages
+    {
+        private final Resource m_resource;
+        public final Map<String, Blame> m_exportedPkgs = new HashMap();
+        public final Map<String, List<Blame>> m_importedPkgs = new HashMap();
+        public final Map<String, List<Blame>> m_requiredPkgs = new HashMap();
+        public final Map<String, List<Blame>> m_usedPkgs = new HashMap();
+
+        public Packages(Resource resource)
+        {
+            m_resource = resource;
+        }
+    }
+
+    private static class Blame
+    {
+        public final Capability m_cap;
+        public final List<Requirement> m_reqs;
+
+        public Blame(Capability cap, List<Requirement> reqs)
+        {
+            m_cap = cap;
+            m_reqs = reqs;
+        }
+
+        @Override
+        public String toString()
+        {
+            return m_cap.getResource()
+                + "." + m_cap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE)
+                + (((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)
+                && m_cap.equals(((Blame) o).m_cap);
+        }
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ShadowList.java b/resolver/src/main/java/org/apache/felix/resolver/ShadowList.java
new file mode 100644
index 0000000..05734da
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/ShadowList.java
@@ -0,0 +1,157 @@
+/*
+ * 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.resolver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+public class ShadowList<T> implements List<T>
+{
+    private final List<T> m_original;
+    private final List<T> m_shadow;
+
+    public ShadowList(List<T> original)
+    {
+        m_original = original;
+        m_shadow = new ArrayList<T>(original);
+    }
+
+    public List<T> getOriginal()
+    {
+        return m_original;
+    }
+
+    public int size()
+    {
+        return m_shadow.size();
+    }
+
+    public boolean isEmpty()
+    {
+        return m_shadow.isEmpty();
+    }
+
+    public boolean contains(Object o)
+    {
+        return m_shadow.contains(o);
+    }
+
+    public Iterator<T> iterator()
+    {
+        return m_shadow.iterator();
+    }
+
+    public Object[] toArray()
+    {
+        return m_shadow.toArray();
+    }
+
+    public <T> T[] toArray(T[] ts)
+    {
+        return m_shadow.toArray(ts);
+    }
+
+    public boolean add(T e)
+    {
+        return m_shadow.add(e);
+    }
+
+    public boolean remove(Object o)
+    {
+        return m_shadow.remove(o);
+    }
+
+    public boolean containsAll(Collection<?> clctn)
+    {
+        return m_shadow.containsAll(clctn);
+    }
+
+    public boolean addAll(Collection<? extends T> clctn)
+    {
+        return m_shadow.addAll(clctn);
+    }
+
+    public boolean addAll(int i, Collection<? extends T> clctn)
+    {
+        return m_shadow.addAll(i, clctn);
+    }
+
+    public boolean removeAll(Collection<?> clctn)
+    {
+        return m_shadow.removeAll(clctn);
+    }
+
+    public boolean retainAll(Collection<?> clctn)
+    {
+        return m_shadow.retainAll(clctn);
+    }
+
+    public void clear()
+    {
+        m_shadow.clear();
+    }
+
+    public T get(int i)
+    {
+        return m_shadow.get(i);
+    }
+
+    public T set(int i, T e)
+    {
+        return m_shadow.set(i, e);
+    }
+
+    public void add(int i, T e)
+    {
+        m_shadow.add(i, e);
+    }
+
+    public T remove(int i)
+    {
+        return m_shadow.remove(i);
+    }
+
+    public int indexOf(Object o)
+    {
+        return m_shadow.indexOf(o);
+    }
+
+    public int lastIndexOf(Object o)
+    {
+        return m_shadow.lastIndexOf(o);
+    }
+
+    public ListIterator<T> listIterator()
+    {
+        return m_shadow.listIterator();
+    }
+
+    public ListIterator<T> listIterator(int i)
+    {
+        return m_shadow.listIterator(i);
+    }
+
+    public List<T> subList(int i, int i1)
+    {
+        return m_shadow.subList(i, i1);
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/SimpleHostedCapability.java b/resolver/src/main/java/org/apache/felix/resolver/SimpleHostedCapability.java
new file mode 100644
index 0000000..98e2d4f
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/SimpleHostedCapability.java
@@ -0,0 +1,61 @@
+/*
+ * 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.resolver;
+
+import java.util.Map;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.service.resolver.HostedCapability;
+
+class SimpleHostedCapability implements HostedCapability
+{
+    private final Resource m_host;
+    private final Capability m_cap;
+
+    SimpleHostedCapability(Resource host, Capability cap)
+    {
+        m_host = host;
+        m_cap = cap;
+    }
+
+    public Resource getResource()
+    {
+        return m_host;
+    }
+
+    public Capability getDeclaredCapability()
+    {
+        return m_cap;
+    }
+
+    public String getNamespace()
+    {
+        return m_cap.getNamespace();
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_cap.getDirectives();
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_cap.getAttributes();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Util.java b/resolver/src/main/java/org/apache/felix/resolver/Util.java
new file mode 100644
index 0000000..e9ab8e6
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/Util.java
@@ -0,0 +1,100 @@
+/*
+ * 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.resolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class Util
+{
+    public static String getSymbolicName(Resource resource)
+    {
+        List<Capability> caps = resource.getCapabilities(null);
+        for (Capability cap : caps)
+        {
+            if (cap.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE))
+            {
+                return cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE).toString();
+            }
+        }
+        return null;
+    }
+
+    public static Version getVersion(Resource resource)
+    {
+        List<Capability> caps = resource.getCapabilities(null);
+        for (Capability cap : caps)
+        {
+            if (cap.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE))
+            {
+                return (Version)
+                    cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+            }
+        }
+        return null;
+    }
+
+    public static boolean isFragment(Resource resource)
+    {
+        List<Capability> caps = resource.getCapabilities(null);
+        for (Capability cap : caps)
+        {
+            if (cap.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE))
+            {
+                String type = (String)
+                    cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE);
+                return (type != null) && type.equals(IdentityNamespace.TYPE_FRAGMENT);
+            }
+        }
+        return false;
+    }
+
+    public static boolean isOptional(Requirement req)
+    {
+        String resolution = req.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+        return ((resolution == null)
+            || resolution.equalsIgnoreCase(Namespace.RESOLUTION_OPTIONAL));
+    }
+
+    public static List<Requirement> getDynamicRequirements(List<Requirement> reqs)
+    {
+        List<Requirement> result = new ArrayList<Requirement>();
+        if (reqs != null)
+        {
+            for (Requirement req : reqs)
+            {
+                String resolution = req.getDirectives()
+                    .get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+                if ((resolution != null)
+                    && resolution.equals(PackageNamespace.RESOLUTION_DYNAMIC))
+                {
+                    result.add(req);
+                }
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/WireImpl.java b/resolver/src/main/java/org/apache/felix/resolver/WireImpl.java
new file mode 100644
index 0000000..7af9b87
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/WireImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.resolver;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+
+class WireImpl implements Wire
+{
+    private final Resource m_requirer;
+    private final Requirement m_req;
+    private final Resource m_provider;
+    private final Capability m_cap;
+
+    public WireImpl(
+        Resource requirer, Requirement req,
+        Resource provider, Capability cap)
+    {
+        m_requirer = requirer;
+        m_req = req;
+        m_provider = provider;
+        m_cap = cap;
+    }
+
+    public Resource getRequirer()
+    {
+        return m_requirer;
+    }
+
+    public Requirement getRequirement()
+    {
+        return m_req;
+    }
+
+    public Resource getProvider()
+    {
+        return m_provider;
+    }
+
+    public Capability getCapability()
+    {
+        return m_cap;
+    }
+
+    @Override
+    public String toString()
+    {
+        return m_req
+            + " -> "
+            + "[" + m_provider + "]";
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java b/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
new file mode 100644
index 0000000..9bbec36
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). 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.apache.felix.resolver;
+
+import java.util.Map;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.service.resolver.HostedCapability;
+
+public class WrappedCapability implements HostedCapability
+{
+    private final Resource m_host;
+    private final Capability m_cap;
+
+    public WrappedCapability(Resource host, Capability cap)
+    {
+        m_host = host;
+        m_cap = cap;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+        {
+            return false;
+        }
+        if (getClass() != obj.getClass())
+        {
+            return false;
+        }
+        final WrappedCapability other = (WrappedCapability) obj;
+        if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
+        {
+            return false;
+        }
+        if (m_cap != other.m_cap && (m_cap == null || !m_cap.equals(other.m_cap)))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int hash = 7;
+        hash = 37 * hash + (m_host != null ? m_host.hashCode() : 0);
+        hash = 37 * hash + (m_cap != null ? m_cap.hashCode() : 0);
+        return hash;
+    }
+
+    public Capability getDeclaredCapability()
+    {
+        return m_cap;
+    }
+
+    public Resource getResource()
+    {
+        return m_host;
+    }
+
+    public String getNamespace()
+    {
+        return m_cap.getNamespace();
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_cap.getDirectives();
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_cap.getAttributes();
+    }
+
+// TODO: RFC-112 - Need impl-specific type.
+//    public List<String> getUses()
+//    {
+//        return m_cap.getUses();
+//    }
+
+    @Override
+    public String toString()
+    {
+        if (m_host == null)
+        {
+            return getAttributes().toString();
+        }
+        if (getNamespace().equals(PackageNamespace.PACKAGE_NAMESPACE))
+        {
+            return "[" + m_host + "] "
+                + getNamespace()
+                + "; "
+                + getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
+        }
+        return "[" + m_host + "] " + getNamespace() + "; " + getAttributes();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/WrappedRequirement.java b/resolver/src/main/java/org/apache/felix/resolver/WrappedRequirement.java
new file mode 100644
index 0000000..a9d66df
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/WrappedRequirement.java
@@ -0,0 +1,102 @@
+/*
+ * 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.resolver;
+
+import java.util.Map;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class WrappedRequirement implements Requirement
+{
+    private final Resource m_host;
+    private final Requirement m_req;
+
+    public WrappedRequirement(Resource host, Requirement req)
+    {
+        m_host = host;
+        m_req = req;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+        {
+            return false;
+        }
+        if (getClass() != obj.getClass())
+        {
+            return false;
+        }
+        final WrappedRequirement other = (WrappedRequirement) obj;
+        if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
+        {
+            return false;
+        }
+        if (m_req != other.m_req && (m_req == null || !m_req.equals(other.m_req)))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int hash = 7;
+        hash = 37 * hash + (m_host != null ? m_host.hashCode() : 0);
+        hash = 37 * hash + (m_req != null ? m_req.hashCode() : 0);
+        return hash;
+    }
+
+    public Requirement getDeclaredRequirement()
+    {
+        return m_req;
+    }
+
+    public Resource getResource()
+    {
+        return m_host;
+    }
+
+    public String getNamespace()
+    {
+        return m_req.getNamespace();
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_req.getDirectives();
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_req.getAttributes();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "[" + m_host + "] "
+            + getNamespace()
+            + "; "
+            + getDirectives().get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/WrappedResource.java b/resolver/src/main/java/org/apache/felix/resolver/WrappedResource.java
new file mode 100644
index 0000000..693e8bb
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/WrappedResource.java
@@ -0,0 +1,127 @@
+/*
+ * 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.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+class WrappedResource implements Resource
+{
+    private final Resource m_host;
+    private final List<Resource> m_fragments;
+    private List<Capability> m_cachedCapabilities = null;
+    private List<Requirement> m_cachedRequirements = null;
+
+    public WrappedResource(Resource host, List<Resource> fragments)
+    {
+        m_host = host;
+        m_fragments = fragments;
+    }
+
+    public Resource getDeclaredResource()
+    {
+        return m_host;
+    }
+
+    public List<Resource> getFragments()
+    {
+        return m_fragments;
+    }
+
+    public List<Capability> getCapabilities(String namespace)
+    {
+        if (m_cachedCapabilities == null)
+        {
+            List<Capability> caps = new ArrayList<Capability>();
+
+            // Wrap host capabilities.
+            for (Capability cap : m_host.getCapabilities(null))
+            {
+                caps.add(new WrappedCapability(this, cap));
+            }
+
+            // Wrap fragment capabilities.
+            if (m_fragments != null)
+            {
+                for (Resource fragment : m_fragments)
+                {
+                    for (Capability cap : fragment.getCapabilities(null))
+                    {
+                        // Filter out identity capabilities, since they
+                        // are not part of the fragment payload.
+                        if (!cap.getNamespace()
+                            .equals(IdentityNamespace.IDENTITY_NAMESPACE))
+                        {
+                            caps.add(new WrappedCapability(this,  cap));
+                        }
+                    }
+                }
+            }
+            m_cachedCapabilities = Collections.unmodifiableList(caps);
+        }
+        return m_cachedCapabilities;
+    }
+
+    public List<Requirement> getRequirements(String namespace)
+    {
+        if (m_cachedRequirements == null)
+        {
+            List<Requirement> reqs = new ArrayList<Requirement>();
+
+            // Wrap host requirements.
+            for (Requirement req : m_host.getRequirements(null))
+            {
+                reqs.add(new WrappedRequirement(this, req));
+            }
+
+            // Wrap fragment requirements.
+            if (m_fragments != null)
+            {
+                for (Resource fragment : m_fragments)
+                {
+                    for (Requirement req : fragment.getRequirements(null))
+                    {
+                        // Filter out host and execution environment requirements,
+                        // since they are not part of the fragment payload.
+                        if (!req.getNamespace().equals(HostNamespace.HOST_NAMESPACE)
+                            && !req.getNamespace().equals(
+                                ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE))
+                        {
+                            reqs.add(new WrappedRequirement(this, req));
+                        }
+                    }
+                }
+            }
+            m_cachedRequirements = Collections.unmodifiableList(reqs);
+        }
+        return m_cachedRequirements;
+    }
+
+    public String toString()
+    {
+        return m_host.toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/BundleCapability.java b/resolver/src/main/java/org/apache/felix/resolver/test/BundleCapability.java
new file mode 100644
index 0000000..30e096d
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/BundleCapability.java
@@ -0,0 +1,79 @@
+/*
+ * 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.resolver.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+class BundleCapability implements Capability
+{
+    private final Resource m_resource;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+
+    public BundleCapability(Resource resource, String name)
+    {
+        m_resource = resource;
+        m_dirs = new HashMap<String, String>();
+        m_attrs = new HashMap<String, Object>();
+        m_attrs.put(BundleNamespace.BUNDLE_NAMESPACE, name);
+    }
+
+    public String getNamespace()
+    {
+        return BundleNamespace.BUNDLE_NAMESPACE;
+    }
+
+    public void addDirective(String name, String value)
+    {
+        m_dirs.put(name, value);
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public void addAttribute(String name, Object value)
+    {
+        m_attrs.put(name, value);
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Resource getResource()
+    {
+        return m_resource;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getNamespace() + "; "
+            + getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/BundleRequirement.java b/resolver/src/main/java/org/apache/felix/resolver/test/BundleRequirement.java
new file mode 100644
index 0000000..efc8b76
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/BundleRequirement.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+class BundleRequirement implements Requirement
+{
+    private final Resource m_resource;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+
+    public BundleRequirement(Resource resource, String name)
+    {
+        m_resource = resource;
+        m_dirs = new HashMap<String, String>();
+        m_dirs.put(
+            BundleNamespace.REQUIREMENT_FILTER_DIRECTIVE,
+            "(" + BundleNamespace.BUNDLE_NAMESPACE + "=" + name + ")");
+        m_attrs = new HashMap<String, Object>();
+    }
+
+    public String getNamespace()
+    {
+        return BundleNamespace.BUNDLE_NAMESPACE;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Resource getResource()
+    {
+        return m_resource;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getNamespace() + "; "
+            + getDirectives().get(BundleNamespace.REQUIREMENT_FILTER_DIRECTIVE).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java b/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java
new file mode 100644
index 0000000..033efdb
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/IdentityCapability.java
@@ -0,0 +1,67 @@
+/*
+ * 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.resolver.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+class IdentityCapability implements Capability
+{
+    private final Resource m_resource;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+
+    public IdentityCapability(Resource resource, String name)
+    {
+        m_resource = resource;
+        m_dirs = new HashMap<String, String>();
+        m_attrs = new HashMap<String, Object>();
+        m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
+    }
+
+    public String getNamespace()
+    {
+        return IdentityNamespace.IDENTITY_NAMESPACE;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Resource getResource()
+    {
+        return m_resource;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getNamespace() + "; "
+            + getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/Main.java b/resolver/src/main/java/org/apache/felix/resolver/test/Main.java
new file mode 100644
index 0000000..6392e73
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/Main.java
@@ -0,0 +1,180 @@
+/*
+ * 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.resolver.test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.felix.resolver.Logger;
+import org.apache.felix.resolver.ResolverImpl;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.resolver.Resolver;
+
+public class Main
+{
+    public static void main(String[] args) throws ResolutionException
+    {
+        Resolver resolver = new ResolverImpl(new Logger(Logger.LOG_DEBUG));
+
+        Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
+        Map<Requirement, List<Capability>> candMap = new HashMap<Requirement, List<Capability>>();
+
+        System.out.println("\nSCENARIO 1\n");
+        List<Resource> mandatory = populateScenario1(wirings, candMap);
+        ResolveContextImpl rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
+        Map<Resource, List<Wire>> wireMap = resolver.resolve(rci);
+        System.out.println("RESULT " + wireMap);
+
+        System.out.println("\nSCENARIO 2\n");
+        mandatory = populateScenario2(wirings, candMap);
+        rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
+        wireMap = resolver.resolve(rci);
+        System.out.println("RESULT " + wireMap);
+
+        System.out.println("\nSCENARIO 3\n");
+        mandatory = populateScenario3(wirings, candMap);
+        rci = new ResolveContextImpl(wirings, candMap, mandatory, Collections.EMPTY_LIST);
+        wireMap = resolver.resolve(rci);
+        System.out.println("RESULT " + wireMap);
+    }
+
+    private static List<Resource> populateScenario1(
+        Map<Resource, Wiring> wirings, Map<Requirement, List<Capability>> candMap)
+    {
+        wirings.clear();
+        candMap.clear();
+
+        ResourceImpl exporter = new ResourceImpl("A");
+        exporter.addCapability(new PackageCapability(exporter, "foo"));
+        ResourceImpl importer = new ResourceImpl("B");
+        importer.addRequirement(new PackageRequirement(importer, "foo"));
+        candMap.put(
+            importer.getRequirements(null).get(0),
+            exporter.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE));
+        List<Resource> resources = new ArrayList<Resource>();
+        resources.add(importer);
+        return resources;
+    }
+
+    private static List<Resource> populateScenario2(
+        Map<Resource, Wiring> wirings, Map<Requirement, List<Capability>> candMap)
+    {
+        wirings.clear();
+        candMap.clear();
+
+        List<Capability> fooCands = new ArrayList<Capability>();
+        List<Capability> barCands = new ArrayList<Capability>();
+
+        // A
+        ResourceImpl a = new ResourceImpl("A");
+        PackageCapability p = new PackageCapability(a, "foo");
+        a.addCapability(p);
+        fooCands.add(p);
+
+        // B
+        ResourceImpl b = new ResourceImpl("B");
+        p = new PackageCapability(b, "foo");
+        b.addCapability(p);
+        fooCands.add(p);
+
+        p = new PackageCapability(b, "bar");
+        p.addDirective(PackageNamespace.CAPABILITY_USES_DIRECTIVE, "foo");
+        b.addCapability(p);
+        barCands.add(p);
+
+        // C
+        ResourceImpl c = new ResourceImpl("C");
+        Requirement r = new PackageRequirement(c, "foo");
+        c.addRequirement(r);
+        candMap.put(r, fooCands);
+
+        r = new PackageRequirement(c, "bar");
+        c.addRequirement(r);
+        candMap.put(r, barCands);
+
+        // Mandatory resources
+        List<Resource> resources = new ArrayList<Resource>();
+        resources.add(c);
+        return resources;
+    }
+
+    private static List<Resource> populateScenario3(
+        Map<Resource, Wiring> wirings, Map<Requirement, List<Capability>> candMap)
+    {
+        wirings.clear();
+        candMap.clear();
+
+        List<Capability> resourcesCands = new ArrayList<Capability>();
+        List<Capability> dResourcesCands = new ArrayList<Capability>();
+        List<Capability> eBundleDCands = new ArrayList<Capability>();
+        List<Capability> eResourcesCands = new ArrayList<Capability>();
+
+        // B
+        ResourceImpl b = new ResourceImpl("B");
+        PackageCapability pc = new PackageCapability(b, "resources");
+        b.addCapability(pc);
+        eResourcesCands.add(pc);
+
+        // C
+        ResourceImpl c = new ResourceImpl("C");
+        pc = new PackageCapability(c, "resources");
+        c.addCapability(pc);
+        eResourcesCands.add(pc);
+        dResourcesCands.add(pc);
+
+        // D
+        ResourceImpl d = new ResourceImpl("D");
+        pc = new PackageCapability(d, "export");
+        pc.addDirective(Namespace.CAPABILITY_USES_DIRECTIVE, "resources");
+        d.addCapability(pc);
+
+        BundleCapability bc = new BundleCapability(d, "D");
+        bc.addDirective(Namespace.CAPABILITY_USES_DIRECTIVE, "resources");
+        d.addCapability(bc);
+        eBundleDCands.add(bc);
+
+        Requirement r = new PackageRequirement(d, "resources");
+        d.addRequirement(r);
+        candMap.put(r, dResourcesCands);
+
+        // E
+        ResourceImpl e = new ResourceImpl("E");
+        r = new BundleRequirement(e, "D");
+        e.addRequirement(r);
+        candMap.put(r, eBundleDCands);
+
+        r = new PackageRequirement(e, "resources");
+        e.addRequirement(r);
+        candMap.put(r, eResourcesCands);
+
+        // Mandatory resources
+        List<Resource> resources = new ArrayList<Resource>();
+        resources.add(e);
+        return resources;
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/PackageCapability.java b/resolver/src/main/java/org/apache/felix/resolver/test/PackageCapability.java
new file mode 100644
index 0000000..c672ada
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/PackageCapability.java
@@ -0,0 +1,78 @@
+/*
+ * 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.resolver.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+class PackageCapability implements Capability
+{
+    private final Resource m_resource;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+
+    public PackageCapability(Resource resource, String name)
+    {
+        m_resource = resource;
+        m_dirs = new HashMap<String, String>();
+        m_attrs = new HashMap<String, Object>();
+        m_attrs.put(PackageNamespace.PACKAGE_NAMESPACE, name);
+    }
+
+    public String getNamespace()
+    {
+        return PackageNamespace.PACKAGE_NAMESPACE;
+    }
+
+    public void addDirective(String name, String value)
+    {
+        m_dirs.put(name, value);
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public void addAttribute(String name, Object value)
+    {
+        m_attrs.put(name, value);
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Resource getResource()
+    {
+        return m_resource;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getNamespace() + "; "
+            + getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/PackageRequirement.java b/resolver/src/main/java/org/apache/felix/resolver/test/PackageRequirement.java
new file mode 100644
index 0000000..eaf6a9b
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/PackageRequirement.java
@@ -0,0 +1,70 @@
+/*
+ * 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.resolver.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+class PackageRequirement implements Requirement
+{
+    private final Resource m_resource;
+    private final Map<String, String> m_dirs;
+    private final Map<String, Object> m_attrs;
+
+    public PackageRequirement(Resource resource, String name)
+    {
+        m_resource = resource;
+        m_dirs = new HashMap<String, String>();
+        m_dirs.put(
+            PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE,
+            "(" + PackageNamespace.PACKAGE_NAMESPACE + "=" + name + ")");
+        m_attrs = new HashMap<String, Object>();
+    }
+
+    public String getNamespace()
+    {
+        return PackageNamespace.PACKAGE_NAMESPACE;
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_dirs;
+    }
+
+    public Map<String, Object> getAttributes()
+    {
+        return m_attrs;
+    }
+
+    public Resource getResource()
+    {
+        return m_resource;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getNamespace() + "; "
+            + getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/ResolveContextImpl.java b/resolver/src/main/java/org/apache/felix/resolver/test/ResolveContextImpl.java
new file mode 100644
index 0000000..2a5f112
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/ResolveContextImpl.java
@@ -0,0 +1,86 @@
+/*
+ * 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.resolver.test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wiring;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolveContext;
+
+class ResolveContextImpl extends ResolveContext
+{
+    private final Map<Resource, Wiring> m_wirings;
+    private final Map<Requirement, List<Capability>> m_candMap;
+    private final Collection<Resource> m_mandatory;
+    private final Collection<Resource> m_optional;
+
+    public ResolveContextImpl(
+        Map<Resource, Wiring> wirings, Map<Requirement, List<Capability>> candMap,
+        Collection<Resource> mandatory, Collection<Resource> optional)
+    {
+        m_wirings = wirings;
+        m_candMap = candMap;
+        m_mandatory = mandatory;
+        m_optional = optional;
+    }
+
+    @Override
+    public Collection<Resource> getMandatoryResources()
+    {
+        return new ArrayList<Resource>(m_mandatory);
+    }
+
+    @Override
+    public Collection<Resource> getOptionalResources()
+    {
+        return new ArrayList<Resource>(m_optional);
+    }
+
+    @Override
+    public List<Capability> findProviders(Requirement r)
+    {
+        return new ArrayList<Capability>(m_candMap.get(r));
+    }
+
+    @Override
+    public int insertHostedCapability(List<Capability> capabilities, HostedCapability hostedCapability)
+    {
+        int idx = 0;
+        capabilities.add(idx, hostedCapability);
+        return idx;
+    }
+
+    @Override
+    public boolean isEffective(Requirement requirement)
+    {
+        return true;
+    }
+
+    @Override
+    public Map<Resource, Wiring> getWirings()
+    {
+        return m_wirings;
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java b/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java
new file mode 100644
index 0000000..7971f97
--- /dev/null
+++ b/resolver/src/main/java/org/apache/felix/resolver/test/ResourceImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.resolver.test;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class ResourceImpl implements Resource
+{
+    private final List<Capability> m_caps;
+    private final List<Requirement> m_reqs;
+
+    public ResourceImpl(String name)
+    {
+        m_caps = new ArrayList<Capability>();
+        m_caps.add(0, new IdentityCapability(this, name));
+        m_reqs = new ArrayList<Requirement>();
+    }
+
+    public void addCapability(Capability cap)
+    {
+        m_caps.add(cap);
+    }
+
+    public List<Capability> getCapabilities(String namespace)
+    {
+        List<Capability> result = m_caps;
+        if (namespace != null)
+        {
+            result = new ArrayList<Capability>();
+            for (Capability cap : m_caps)
+            {
+                if (cap.getNamespace().equals(namespace))
+                {
+                    result.add(cap);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void addRequirement(Requirement req)
+    {
+        m_reqs.add(req);
+    }
+
+    public List<Requirement> getRequirements(String namespace)
+    {
+        List<Requirement> result = m_reqs;
+        if (namespace != null)
+        {
+            result = new ArrayList<Requirement>();
+            for (Requirement req : m_reqs)
+            {
+                if (req.getNamespace().equals(namespace))
+                {
+                    result.add(req);
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0).toString();
+    }
+}
\ No newline at end of file
diff --git a/resolver/src/main/java/org/osgi/service/resolver/HostedCapability.java b/resolver/src/main/java/org/osgi/service/resolver/HostedCapability.java
new file mode 100644
index 0000000..3c176de
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/HostedCapability.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). 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.service.resolver;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+/**
+ * A capability hosted by a resource.
+ * 
+ * <p>
+ * A HostedCapability is a Capability where the {@link #getResource()} method
+ * returns a Resource that hosts this Capability instead of declaring it. This
+ * is necessary for cases where the declaring Resource of a Capability does not
+ * match the runtime state. For example, this is the case for fragments attached
+ * to a host. Most fragment declared capabilities and requirements become hosted
+ * by the host resource. Since a fragment can attach to multiple hosts, a single
+ * capability can actually be hosted multiple times.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: db698baa07e2ee8b5467871239adb5f0806dc183 $
+ */
+public interface HostedCapability extends Capability {
+
+	/**
+	 * Return the Resource that hosts this Capability.
+	 * 
+	 * @return The Resource that hosts this Capability.
+	 */
+	Resource getResource();
+
+	/**
+	 * Return the Capability hosted by the Resource.
+	 * 
+	 * @return The Capability hosted by the Resource.
+	 */
+	Capability getDeclaredCapability();
+}
diff --git a/resolver/src/main/java/org/osgi/service/resolver/ResolutionException.java b/resolver/src/main/java/org/osgi/service/resolver/ResolutionException.java
new file mode 100644
index 0000000..a626fc9
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/ResolutionException.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). 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.service.resolver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import org.osgi.resource.Requirement;
+
+/**
+ * Indicates failure to resolve a set of requirements.
+ * 
+ * <p>
+ * If a resolution failure is caused by a missing mandatory dependency a
+ * resolver may include any requirements it has considered in the resolution
+ * exception. Clients may access this set of dependencies via the
+ * {@link #getUnresolvedRequirements()} method.
+ * 
+ * <p>
+ * Resolver implementations may extend this class to provide extra state
+ * information about the reason for the resolution failure.
+ * 
+ * @version $Id: 42e5773e3b7e240673874329e5d9e705d0b698c5 $
+ */
+public class ResolutionException extends Exception {
+
+	private static final long				serialVersionUID	= 1L;
+
+	private final Collection<Requirement>	unresolvedRequirements;
+
+	/**
+	 * Create a {@code ResolutionException} with the specified message, cause
+	 * and unresolved requirements.
+	 * 
+	 * @param message The message.
+	 * @param cause The cause of this exception.
+	 * @param unresolvedRequirements The unresolved mandatory requirements from
+	 *        mandatory resources or {@code null} if no unresolved requirements
+	 *        information is provided.
+	 */
+	public ResolutionException(String message, Throwable cause, Collection<Requirement> unresolvedRequirements) {
+		super(message, cause);
+		if ((unresolvedRequirements == null) || unresolvedRequirements.isEmpty()) {
+			this.unresolvedRequirements = emptyCollection();
+		} else {
+			this.unresolvedRequirements = Collections.unmodifiableCollection(new ArrayList<Requirement>(unresolvedRequirements));
+		}
+	}
+
+	/**
+	 * Create a {@code ResolutionException} with the specified message.
+	 * 
+	 * @param message The message.
+	 */
+	public ResolutionException(String message) {
+		super(message);
+		unresolvedRequirements = emptyCollection();
+	}
+
+	/**
+	 * Create a {@code ResolutionException} with the specified cause.
+	 * 
+	 * @param cause The cause of this exception.
+	 */
+	public ResolutionException(Throwable cause) {
+		super(cause);
+		unresolvedRequirements = emptyCollection();
+	}
+
+	private static <T> Collection<T> emptyCollection() {
+		return Collections.EMPTY_LIST;
+	}
+
+	/**
+	 * Return the unresolved requirements, if any, for this exception.
+	 * 
+	 * <p>
+	 * The unresolved requirements are provided for informational purposes and
+	 * the specific set of unresolved requirements that are provided after a
+	 * resolve failure is not defined.
+	 * 
+	 * @return A collection of the unresolved requirements for this exception.
+	 *         The returned collection may be empty if no unresolved
+	 *         requirements information is provided.
+	 */
+	public Collection<Requirement> getUnresolvedRequirements() {
+		return unresolvedRequirements;
+	}
+}
diff --git a/resolver/src/main/java/org/osgi/service/resolver/ResolveContext.java b/resolver/src/main/java/org/osgi/service/resolver/ResolveContext.java
new file mode 100644
index 0000000..5dac453
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/ResolveContext.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). 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.service.resolver;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wiring;
+
+/**
+ * A resolve context provides resources, options and constraints to the
+ * potential solution of a {@link Resolver#resolve(ResolveContext) resolve}
+ * operation.
+ * 
+ * <p>
+ * Resolve Contexts:
+ * <ul>
+ * <li>Specify the mandatory and optional resources to resolve. The mandatory
+ * and optional resources must be consistent and correct. For example, they must
+ * not violate the singleton policy of the implementer.</li>
+ * <li>Provide {@link Capability capabilities} that the Resolver can use to
+ * satisfy {@link Requirement requirements} via the
+ * {@link #findProviders(Requirement)} method</li>
+ * <li>Constrain solutions via the {@link #getWirings()} method. A wiring
+ * consists of a map of existing {@link Resource resources} to {@link Wiring
+ * wiring}.</li>
+ * <li>Filter requirements that are part of a resolve operation via the
+ * {@link #isEffective(Requirement)}.</li>
+ * </ul>
+ * 
+ * <p>
+ * A resolver may call the methods on the resolve context any number of times
+ * during a resolve operation using any thread. Implementors should ensure that
+ * this class is properly thread safe.
+ * 
+ * <p>
+ * Except for {@link #insertHostedCapability(List, HostedCapability)}, the
+ * resolve context methods must be <i>idempotent</i>. This means that resources
+ * must have constant capabilities and requirements and the resolve context must
+ * return a consistent set of capabilities, wires and effective requirements.
+ * 
+ * @ThreadSafe
+ * @version $Id: f92eae32ab6fadb25e13d226458d6af50e8dcbba $
+ */
+public abstract class ResolveContext {
+	/**
+	 * Return the resources that must be resolved for this resolve context.
+	 * 
+	 * <p>
+	 * The default implementation returns an empty collection.
+	 * 
+	 * @return The resources that must be resolved for this resolve context. May
+	 *         be empty if there are no mandatory resources.
+	 */
+	public Collection<Resource> getMandatoryResources() {
+		return emptyCollection();
+	}
+
+	/**
+	 * Return the resources that the resolver should attempt to resolve for this
+	 * resolve context. Inability to resolve one of the specified resources will
+	 * not result in a resolution exception.
+	 * 
+	 * <p>
+	 * The default implementation returns an empty collection.
+	 * 
+	 * @return The resources that the resolver should attempt to resolve for
+	 *         this resolve context. May be empty if there are no mandatory
+	 *         resources.
+	 */
+	public Collection<Resource> getOptionalResources() {
+		return emptyCollection();
+	}
+
+	private static <T> Collection<T> emptyCollection() {
+		return Collections.EMPTY_LIST;
+	}
+
+	/**
+	 * Find Capabilities that match the given Requirement.
+	 * <p>
+	 * The returned list contains {@link Capability} objects where the Resource
+	 * must be the declared Resource of the Capability. The Resolver can then
+	 * add additional {@link HostedCapability} objects with the
+	 * {@link #insertHostedCapability(List, HostedCapability)} method when it,
+	 * for example, attaches fragments. Those {@link HostedCapability} objects
+	 * will then use the host's Resource which likely differs from the declared
+	 * Resource of the corresponding Capability.
+	 * 
+	 * <p>
+	 * The returned list is in priority order such that the Capabilities with a
+	 * lower index have a preference over those with a higher index. The
+	 * resolver must use the
+	 * {@link #insertHostedCapability(List, HostedCapability)} method to add
+	 * additional Capabilities to maintain priority order. In general, this is
+	 * necessary when the Resolver uses Capabilities declared in a Resource but
+	 * that must originate from an attached host.
+	 * 
+	 * <p>
+	 * Each returned Capability must match the given Requirement. This implies
+	 * that the filter in the Requirement must match as well as any namespace
+	 * specific directives. For example, the mandatory attributes for the
+	 * {@code osgi.wiring.package} namespace.
+	 * 
+	 * @param requirement The requirement that a resolver is attempting to
+	 *        satisfy. Must not be {@code null}.
+	 * @return A list of {@link Capability} objects that match the specified
+	 *         requirement.
+	 */
+	public abstract List<Capability> findProviders(Requirement requirement);
+
+	/**
+	 * Add a {@link HostedCapability} to the list of capabilities returned from
+	 * {@link #findProviders(Requirement)}.
+	 * 
+	 * <p>
+	 * This method is used by the {@link Resolver} to add Capabilities that are
+	 * hosted by another Resource to the list of Capabilities returned from
+	 * {@link #findProviders(Requirement)}. This function is necessary to allow
+	 * fragments to attach to hosts, thereby changing the origin of a
+	 * Capability. This method must insert the specified HostedCapability in a
+	 * place that makes the list maintain the preference order. It must return
+	 * the index in the list of the inserted {@link HostedCapability}.
+	 * 
+	 * @param capabilities The list returned from
+	 *        {@link #findProviders(Requirement)}. Must not be {@code null}.
+	 * @param hostedCapability The HostedCapability to insert in the specified
+	 *        list. Must not be {@code null}.
+	 * @return The index in the list of the inserted HostedCapability.
+	 * 
+	 */
+	public abstract int insertHostedCapability(List<Capability> capabilities, HostedCapability hostedCapability);
+
+	/**
+	 * Test if a given requirement should be wired in the resolve operation. If
+	 * this method returns {@code false}, then the resolver should ignore this
+	 * requirement during the resolve operation.
+	 * 
+	 * <p>
+	 * The primary use case for this is to test the {@code effective} directive
+	 * on the requirement, though implementations are free to use any effective
+	 * test.
+	 * 
+	 * @param requirement The Requirement to test. Must not be {@code null}.
+	 * @return {@code true} if the requirement should be considered as part of
+	 *         the resolve operation.
+	 */
+	public abstract boolean isEffective(Requirement requirement);
+
+	/**
+	 * Returns the wirings for existing resolved resources.
+	 * 
+	 * <p>
+	 * For example, if this resolve context is for an OSGi framework, then the
+	 * result would contain all the currently resolved bundles with each
+	 * bundle's current wiring.
+	 * 
+	 * <p>
+	 * Multiple calls to this method for this resolve context must return the
+	 * same result.
+	 * 
+	 * @return The wirings for existing resolved resources. The returned map is
+	 *         unmodifiable.
+	 */
+	public abstract Map<Resource, Wiring> getWirings();
+}
diff --git a/resolver/src/main/java/org/osgi/service/resolver/Resolver.java b/resolver/src/main/java/org/osgi/service/resolver/Resolver.java
new file mode 100644
index 0000000..d451ade
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/Resolver.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) OSGi Alliance (2006, 2012). 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.
+ */
+
+// This document is an experimental draft to enable interoperability
+// between bundle repositories. There is currently no commitment to
+// turn this draft into an official specification.
+
+package org.osgi.service.resolver;
+
+import java.util.List;
+import java.util.Map;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+
+/**
+ * A resolver service resolves the specified resources in the context supplied
+ * by the caller.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: dfb89b8d09af62ecf62321b80d7e2310512f27a1 $
+ */
+public interface Resolver {
+	/**
+	 * Resolve the specified resolve context and return any new resources and
+	 * wires to the caller.
+	 * 
+	 * <p>
+	 * The resolver considers two groups of resources:
+	 * <ul>
+	 * <li>Mandatory - any resource in the
+	 * {@link ResolveContext#getMandatoryResources() mandatory group} must be
+	 * resolved. A failure to satisfy any mandatory requirement for these
+	 * resources will result in throwing a {@link ResolutionException}</li>
+	 * <li>Optional - any resource in the
+	 * {@link ResolveContext#getOptionalResources() optional group} may be
+	 * resolved. A failure to satisfy a mandatory requirement for a resource in
+	 * this group will not fail the overall resolution but no resources or wires
+	 * will be returned for that resource.</li>
+	 * </ul>
+	 * 
+	 * <p>
+	 * The resolve method returns the delta between the start state defined by
+	 * {@link ResolveContext#getWirings()} and the end resolved state. That is,
+	 * only new resources and wires are included.
+	 * 
+	 * <p>
+	 * The behavior of the resolver is not defined if the specified resolve
+	 * context supplies inconsistent information.
+	 * 
+	 * @param context The resolve context for the resolve operation. Must not be
+	 *        {@code null}.
+	 * @return The new resources and wires required to satisfy the specified
+	 *         resolve context. The returned map is the property of the caller
+	 *         and can be modified by the caller.
+	 * @throws ResolutionException If the resolution cannot be satisfied.
+	 */
+	Map<Resource, List<Wire>> resolve(ResolveContext context) throws ResolutionException;
+}
diff --git a/resolver/src/main/java/org/osgi/service/resolver/package-info.java b/resolver/src/main/java/org/osgi/service/resolver/package-info.java
new file mode 100644
index 0000000..d361a48
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2012). 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.
+ */
+
+/**
+ * Resolver Service Package Version 1.0.
+ * 
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ * 
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.resolver; version="[1.0,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code  Import-Package: org.osgi.service.resolver; version="[1.0,1.1)"}
+ * 
+ * @version $Id: db1706d83ca104187f77cb1feb7cf52b92b3740d $
+ */
+
+package org.osgi.service.resolver;
+
diff --git a/resolver/src/main/java/org/osgi/service/resolver/packageinfo b/resolver/src/main/java/org/osgi/service/resolver/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/resolver/src/main/java/org/osgi/service/resolver/packageinfo
@@ -0,0 +1 @@
+version 1.0
