Apply patch FELIX-4498 to improve handling of optional requirements.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1589878 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Candidates.java b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
index 366605b..b5429eb 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
@@ -746,6 +746,11 @@
         return m_candidateMap.get(req);
     }
 
+    public void clearCandidates(Requirement req)
+    {
+        m_candidateMap.remove(req);
+    }
+
     /**
      * Merges fragments into their hosts. It does this by wrapping all host
      * modules and attaching their selected fragments, removing all unselected
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
index d0e3967..d6d3910 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
@@ -1237,11 +1237,15 @@
                             // 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))
+                            if ((candidates != null) && (candidates.size() > 1 || Util.isOptional(req)))
                             {
                                 mutated.add(req);
                                 // Remove the conflicting candidate.
                                 candidates.remove(0);
+                                if (candidates.isEmpty())
+                                {
+                                    permutation.clearCandidates(req);
+                                }
                                 // Continue with the next uses constraint.
                                 break;
                             }
@@ -1346,11 +1350,15 @@
                             // 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))
+                            if ((candidates != null) && (candidates.size() > 1 || Util.isOptional(req)))
                             {
                                 mutated.add(req);
                                 // Remove the conflicting candidate.
                                 candidates.remove(0);
+                                if (candidates.isEmpty())
+                                {
+                                    permutation.clearCandidates(req);
+                                }
                                 // Continue with the next uses constraint.
                                 break;
                             }
@@ -1470,11 +1478,15 @@
         if (!Util.isMultiple(req))
         {
             List<Capability> candidates = allCandidates.getCandidates(req);
-            if ((candidates != null) && (candidates.size() > 1))
+            if ((candidates != null) && (candidates.size() > 1 || Util.isOptional(req)))
             {
                 Candidates perm = allCandidates.copy();
                 candidates = perm.getCandidates(req);
                 candidates.remove(0);
+                if (candidates.isEmpty())
+                {
+                    perm.clearCandidates(req);
+                }
                 permutations.add(perm);
             }
         }