Merge dynamic imports into normal imports. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102840 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
index 7ebc611..a390407 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -64,7 +64,6 @@
 
     private final List<BundleCapability> m_declaredCaps;
     private final List<BundleRequirement> m_declaredReqs;
-    private final List<BundleRequirement> m_declaredDynamicReqs;
     private final List<R4Library> m_declaredNativeLibs;
     private final int m_declaredActivationPolicy;
     private final List<String> m_activationIncludes;
@@ -114,7 +113,6 @@
         m_version = null;
         m_declaredCaps = Collections.EMPTY_LIST;
         m_declaredReqs = Collections.EMPTY_LIST;
-        m_declaredDynamicReqs = Collections.EMPTY_LIST;
         m_declaredNativeLibs = null;
         m_declaredActivationPolicy = EAGER_ACTIVATION;
         m_activationExcludes = null;
@@ -148,7 +146,6 @@
         m_version = mp.getBundleVersion();
         m_declaredCaps = mp.isExtension() ? null : mp.getCapabilities();
         m_declaredReqs = mp.getRequirements();
-        m_declaredDynamicReqs = mp.getDynamicRequirements();
         m_declaredNativeLibs = mp.getLibraries();
         m_declaredActivationPolicy = mp.getActivationPolicy();
         m_activationExcludes = (mp.getActivationExcludeDirective() == null)
@@ -283,11 +280,6 @@
         return m_manifestVersion;
     }
 
-    public List<BundleRequirement> getDeclaredDynamicRequirements()
-    {
-        return m_declaredDynamicReqs;
-    }
-
     public List<R4Library> getDeclaredNativeLibraries()
     {
         return m_declaredNativeLibs;
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index 60588b1..00e1fd7 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -79,7 +79,6 @@
     private final Map<String, List<BundleRevision>> m_requiredPkgs;
     private final List<BundleCapability> m_resolvedCaps;
     private final List<BundleRequirement> m_resolvedReqs;
-    private final List<BundleRequirement> m_resolvedDynamicReqs;
     private final List<R4Library> m_resolvedNativeLibs;
     private final List<Content> m_fragmentContents;
 
@@ -227,29 +226,6 @@
         }
         m_resolvedReqs = Collections.unmodifiableList(reqList);
 
-        List<BundleRequirement> dynReqList = (m_revision.getDeclaredDynamicRequirements() == null)
-            ? new ArrayList()
-            : new ArrayList(m_revision.getDeclaredDynamicRequirements());
-        for (int fragIdx = 0;
-            (m_fragments != null) && (fragIdx < m_fragments.size());
-            fragIdx++)
-        {
-            List<BundleRequirement> reqs =
-                ((BundleRevisionImpl) m_fragments.get(fragIdx))
-                    .getDeclaredDynamicRequirements();
-            for (int reqIdx = 0;
-                (reqs != null) && (reqIdx < reqs.size());
-                reqIdx++)
-            {
-                if (reqs.get(reqIdx).getNamespace().equals(
-                    BundleCapabilityImpl.PACKAGE_NAMESPACE))
-                {
-                    dynReqList.add(reqs.get(reqIdx));
-                }
-            }
-        }
-        m_resolvedDynamicReqs = Collections.unmodifiableList(dynReqList);
-
         List<R4Library> libList = (m_revision.getDeclaredNativeLibraries() == null)
             ? new ArrayList<R4Library>()
             : new ArrayList<R4Library>(m_revision.getDeclaredNativeLibraries());
@@ -381,11 +357,6 @@
         return result;
     }
 
-    public List<BundleRequirement> getDynamicRequirements()
-    {
-        return m_resolvedDynamicReqs;
-    }
-
     public List<R4Library> getNativeLibraries()
     {
         return m_resolvedNativeLibs;
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index ba0f2ff..d3f2f4f 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -4259,7 +4259,7 @@
             // If the revision doesn't have dynamic imports, then just return
             // immediately.
             List<BundleRequirement> dynamics =
-                ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements();
+                Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
             if ((dynamics == null) || dynamics.isEmpty())
             {
                 return false;
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index 066a303..bd61f3d 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -233,6 +233,14 @@
         {
             BundleRequirement req = remainingReqs.remove(0);
 
+            // Ignore dynamic requirements.
+            String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+// TODO: OSGi R4.3 - Use proper "dynamic" constant.
+            if ((resolution != null) && resolution.equals("dynamic"))
+            {
+                continue;
+            }
+
             // Get satisfying candidates and populate their candidates if necessary.
             ResolveException rethrow = null;
             SortedSet<BundleCapability> candidates =
@@ -727,7 +735,7 @@
                 }
             }
 
-            // Copies candidates for fragment requirements to the host.
+            // Copy candidates for fragment requirements to the host.
             // This doesn't record the reverse dependency, but that
             // information should not be needed at this point anymore.
             for (BundleRequirement r : hostRevision.getDeclaredRequirements(null))
@@ -991,12 +999,12 @@
                     System.out.println("    " + req + ": " + candidates);
                 }
             }
-// TODO: OSGi R4.3 - We need to get dynamic requirements using public API
-//       then we might not need to make the BundleWiringImpl and BundleRevisionImpl
-//       classes public.
+// TODO: OSGi R4.3 - Need to check what getWiring().getRequirements() returns
+//       with respect to dynamic imports; is it the union of all declared
+//       dynamic imports from fragments and host?
             reqs = (br.getWiring() != null)
-                ? ((BundleWiringImpl) br.getWiring()).getDynamicRequirements()
-                : ((BundleRevisionImpl) br).getDeclaredDynamicRequirements();
+                ? Util.getDynamicRequirements(br.getWiring().getRequirements(null))
+                : Util.getDynamicRequirements(br.getDeclaredRequirements(null));
             for (BundleRequirement req : reqs)
             {
                 Set<BundleCapability> candidates = m_candidateMap.get(req);
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index 78cf088..80cb321 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -90,7 +90,9 @@
 
                     // If the requested revision is a fragment, then
                     // ultimately we will verify the host.
-                    BundleRequirement hostReq = getHostRequirement(revision);
+                    List<BundleRequirement> hostReqs =
+                        revision.getDeclaredRequirements(BundleCapabilityImpl.HOST_NAMESPACE);
+
                     BundleRevision target = revision;
 
                     do
@@ -107,9 +109,9 @@
 
                         // If we are resolving a fragment, then we
                         // actually want to verify its host.
-                        if (hostReq != null)
+                        if (!hostReqs.isEmpty())
                         {
-                            target = allCandidates.getCandidates(hostReq)
+                            target = allCandidates.getCandidates(hostReqs.get(0))
                                 .iterator().next().getRevision();
                         }
 
@@ -323,30 +325,6 @@
         return singletons;
     }
 
-    private static BundleCapability getHostCapability(BundleRevision br)
-    {
-        for (BundleCapability c : br.getDeclaredCapabilities(null))
-        {
-            if (c.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
-            {
-                return c;
-            }
-        }
-        return null;
-    }
-
-    private static BundleRequirement getHostRequirement(BundleRevision br)
-    {
-        for (BundleRequirement r : br.getDeclaredRequirements(null))
-        {
-            if (r.getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE))
-            {
-                return r;
-            }
-        }
-        return null;
-    }
-
     private static Candidates getDynamicImportCandidates(
         ResolverState state, BundleRevision revision, String pkgName)
     {
@@ -360,7 +338,7 @@
         // If the revision doesn't have dynamic imports, then just return
         // immediately.
         List<BundleRequirement> dynamics =
-            ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements();
+            Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
         if ((dynamics == null) || dynamics.isEmpty())
         {
             return null;
@@ -496,7 +474,7 @@
             // so check to see if there are candidates for any of its dynamic
             // imports.
             for (BundleRequirement req
-                : ((BundleWiringImpl) revision.getWiring()).getDynamicRequirements())
+                : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
             {
                 // Get the candidates for the current requirement.
                 SortedSet<BundleCapability> candCaps =
@@ -520,18 +498,23 @@
         {
             for (BundleRequirement req : revision.getDeclaredRequirements(null))
             {
-                // Get the candidates for the current requirement.
-                SortedSet<BundleCapability> candCaps =
-                    allCandidates.getCandidates((BundleRequirementImpl) req);
-                // Optional requirements may not have any candidates.
-                if (candCaps == null)
+                String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+// TODO: OSGi R4.3 - Use proper "dynamic" constant.
+                if ((resolution == null) || !resolution.equals("dynamic"))
                 {
-                    continue;
-                }
+                    // Get the candidates for the current requirement.
+                    SortedSet<BundleCapability> candCaps =
+                        allCandidates.getCandidates((BundleRequirementImpl) req);
+                    // Optional requirements may not have any candidates.
+                    if (candCaps == null)
+                    {
+                        continue;
+                    }
 
-                BundleCapability cap = candCaps.iterator().next();
-                reqs.add(req);
-                caps.add(cap);
+                    BundleCapability cap = candCaps.iterator().next();
+                    reqs.add(req);
+                    caps.add(cap);
+                }
             }
         }
 
@@ -1393,9 +1376,11 @@
                     hostWires.add(
                         new ResolverWireImpl(
                             getActualBundleRevision(fragment),
-                            getHostRequirement(fragment),
+                            fragment.getDeclaredRequirements(
+                                BundleCapabilityImpl.HOST_NAMESPACE).get(0),
                             unwrappedRevision,
-                            getHostCapability(unwrappedRevision)));
+                            unwrappedRevision.getDeclaredCapabilities(
+                                BundleCapabilityImpl.HOST_NAMESPACE).get(0)));
                 }
             }
         }
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index 8cc096f..c52e1a5 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -26,15 +26,16 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import org.apache.felix.framework.BundleRevisionImpl;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 
 import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
 
@@ -327,6 +328,24 @@
         return matching;
     }
 
+    public static List<BundleRequirement> getDynamicRequirements(
+        List<BundleRequirement> reqs)
+    {
+        List<BundleRequirement> result = new ArrayList<BundleRequirement>();
+        if (reqs != null)
+        {
+            for (BundleRequirement req : reqs)
+            {
+                String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+                if ((resolution != null) && resolution.equals("dynamic"))
+                {
+                    result.add(req);
+                }
+            }
+        }
+        return result;
+    }
+
     public static BundleWire getWire(BundleRevision br, String name)
     {
         if (br.getWiring() != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index e4020e0..ce075ad 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -46,7 +46,6 @@
     private volatile Version m_bundleVersion;
     private volatile List<BundleCapability> m_capabilities;
     private volatile List<BundleRequirement> m_requirements;
-    private volatile List<BundleRequirement> m_dynamicRequirements;
     private volatile List<R4LibraryClause> m_libraryClauses;
     private volatile boolean m_libraryHeadersOptional = false;
 
@@ -171,7 +170,7 @@
         List<ParsedHeaderClause> dynamicClauses =
             parseStandardHeader((String) headerMap.get(Constants.DYNAMICIMPORT_PACKAGE));
         dynamicClauses = normalizeDynamicImportClauses(m_logger, dynamicClauses, getManifestVersion());
-        m_dynamicRequirements = convertImports(dynamicClauses, owner);
+        List<BundleRequirement> dynamicReqs = convertImports(dynamicClauses, owner);
 
         //
         // Parse Export-Package.
@@ -210,10 +209,11 @@
 
         // Combine all requirements.
         m_requirements = new ArrayList(
-             importReqs.size() + requireReqs.size() + hostReqs.size());
+             importReqs.size() + requireReqs.size() + hostReqs.size() + dynamicReqs.size());
         m_requirements.addAll(importReqs);
         m_requirements.addAll(requireReqs);
         m_requirements.addAll(hostReqs);
+        m_requirements.addAll(dynamicReqs);
 
         //
         // Parse Bundle-NativeCode.
@@ -264,12 +264,13 @@
     {
         // Verify that the values are equals if the package specifies
         // both version and specification-version attributes.
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+        Set dupeSet = new HashSet();
+        for (ParsedHeaderClause clause : clauses)
         {
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
-            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
@@ -284,32 +285,26 @@
             // it to the VersionRange type.
             if ((v != null) || (sv != null))
             {
-                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                clauses.get(clauseIdx).m_attrs.put(
+                clause.m_attrs.put(
                     Constants.VERSION_ATTRIBUTE,
                     VersionRange.parse(v.toString()));
             }
 
             // If bundle version is specified, then convert its type to VersionRange.
-            v = clauses.get(clauseIdx).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+            v = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
             if (v != null)
             {
-                clauses.get(clauseIdx).m_attrs.put(
+                clause.m_attrs.put(
                     Constants.BUNDLE_VERSION_ATTRIBUTE,
                     VersionRange.parse(v.toString()));
             }
-        }
 
-        // Verify java.* is not imported, nor any duplicate imports.
-        Set dupeSet = new HashSet();
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
-        {
-            // Verify that the named package has not already been declared.
-            List<String> paths = clauses.get(clauseIdx).m_paths;
-            for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
+            // Verify java.* is not imported, nor any duplicate imports.
+            for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
             {
-                String pkgName = paths.get(pathIdx);
+                String pkgName = clause.m_paths.get(pathIdx);
                 if (!dupeSet.contains(pkgName))
                 {
                     // Verify that java.* packages are not imported.
@@ -319,7 +314,7 @@
                             "Importing java.* packages not allowed: " + pkgName);
                     }
                     // Make sure a package name was specified.
-                    else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
+                    else if (clause.m_paths.get(pathIdx).length() == 0)
                     {
                         throw new BundleException(
                             "Imported package names cannot be zero length.");
@@ -331,17 +326,11 @@
                     throw new BundleException("Duplicate import: " + pkgName);
                 }
             }
-        }
 
-        if (!mv.equals("2"))
-        {
-            // Check to make sure that R3 bundles have only specified
-            // the 'specification-version' attribute and no directives
-            // on their imports; ignore all unknown attributes.
-            for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+            if (!mv.equals("2"))
             {
                 // R3 bundles cannot have directives on their imports.
-                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
+                if (!clause.m_dirs.isEmpty())
                 {
                     throw new BundleException("R3 imports cannot contain directives.");
                 }
@@ -351,17 +340,16 @@
                 // because the package class normalizes to "version" to avoid having
                 // future special cases. This could be changed if more strict behavior
                 // is required.
-                if (!clauses.get(clauseIdx).m_attrs.isEmpty())
+                if (!clause.m_attrs.isEmpty())
                 {
                     // R3 package requirements should only have version attributes.
-                    Object pkgVersion = new VersionRange(Version.emptyVersion, true, null, true);
-                    for (Entry<String, Object> entry : clauses.get(clauseIdx).m_attrs.entrySet())
+                    Object pkgVersion = clause.m_attrs.get(BundleCapabilityImpl.VERSION_ATTR);
+                    pkgVersion = (pkgVersion == null)
+                        ? new VersionRange(Version.emptyVersion, true, null, true)
+                        : pkgVersion;
+                    for (Entry<String, Object> entry : clause.m_attrs.entrySet())
                     {
-                        if (entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
-                        {
-                            pkgVersion = entry.getValue();
-                        }
-                        else
+                        if (!entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
                         {
                             logger.log(Logger.LOG_WARNING,
                                 "Unknown R3 import attribute: "
@@ -369,15 +357,9 @@
                         }
                     }
 
-                    // Recreate the import to remove any other attributes
-                    // and add version if missing.
-                    Map<String, Object> attrs = new HashMap<String, Object>(1);
-                    attrs.put(
-                        BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
-                    clauses.set(clauseIdx, new ParsedHeaderClause(
-                        clauses.get(clauseIdx).m_paths,
-                        clauses.get(clauseIdx).m_dirs,
-                        attrs));
+                    // Remove all other attributes except package version.
+                    clause.m_attrs.clear();
+                    clause.m_attrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
                 }
             }
         }
@@ -428,12 +410,26 @@
     {
         // Verify that the values are equals if the package specifies
         // both version and specification-version attributes.
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+        for (ParsedHeaderClause clause : clauses)
         {
+            if (!mv.equals("2"))
+            {
+                // R3 bundles cannot have directives on their imports.
+                if (!clause.m_dirs.isEmpty())
+                {
+                    throw new BundleException("R3 imports cannot contain directives.");
+                }
+            }
+
+            // Add the resolution directive to indicate that these are
+            // dynamic imports.
+// TODO: OSGi R4.3 - Use real constant value for "dynamic".
+            clause.m_dirs.put(Constants.RESOLUTION_DIRECTIVE, "dynamic");
+
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
-            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
@@ -448,32 +444,27 @@
             // it to the VersionRange type.
             if ((v != null) || (sv != null))
             {
-                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                clauses.get(clauseIdx).m_attrs.put(
+                clause.m_attrs.put(
                     Constants.VERSION_ATTRIBUTE,
                     VersionRange.parse(v.toString()));
             }
 
             // If bundle version is specified, then convert its type to VersionRange.
-            v = clauses.get(clauseIdx).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
+            v = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
             if (v != null)
             {
-                clauses.get(clauseIdx).m_attrs.put(
+                clause.m_attrs.put(
                     Constants.BUNDLE_VERSION_ATTRIBUTE,
                     VersionRange.parse(v.toString()));
             }
-        }
 
-        // Dynamic imports can have duplicates, so just check for import
-        // of java.*.
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
-        {
-            // Verify that java.* packages are not imported.
-            List<String> paths = clauses.get(clauseIdx).m_paths;
-            for (int pathIdx = 0; pathIdx < paths.size(); pathIdx++)
+            // Dynamic imports can have duplicates, so verify that java.*
+            // packages are not imported.
+            for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
             {
-                String pkgName = paths.get(pathIdx);
+                String pkgName = clause.m_paths.get(pathIdx);
                 if (pkgName.startsWith("java."))
                 {
                     throw new BundleException(
@@ -487,21 +478,6 @@
             }
         }
 
-        if (!mv.equals("2"))
-        {
-            // Check to make sure that R3 bundles have only specified
-            // the 'specification-version' attribute and no directives
-            // on their imports; ignore all unknown attributes.
-            for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
-            {
-                // R3 bundles cannot have directives on their imports.
-                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
-                {
-                    throw new BundleException("R3 imports cannot contain directives.");
-                }
-            }
-        }
-
         return clauses;
     }
 
@@ -511,34 +487,29 @@
         throws BundleException
     {
         // Verify that "java.*" packages are not exported.
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+        for (ParsedHeaderClause clause : clauses)
         {
             // Verify that the named package has not already been declared.
-            for (int pathIdx = 0; pathIdx < clauses.get(clauseIdx).m_paths.size(); pathIdx++)
+            for (int pathIdx = 0; pathIdx < clause.m_paths.size(); pathIdx++)
             {
                 // Verify that java.* packages are not exported.
-                if (clauses.get(clauseIdx).m_paths.get(pathIdx).startsWith("java."))
+                if (clause.m_paths.get(pathIdx).startsWith("java."))
                 {
                     throw new BundleException(
                         "Exporting java.* packages not allowed: "
-                        + clauses.get(clauseIdx).m_paths.get(pathIdx));
+                        + clause.m_paths.get(pathIdx));
                 }
-                else if (clauses.get(clauseIdx).m_paths.get(pathIdx).length() == 0)
+                else if (clause.m_paths.get(pathIdx).length() == 0)
                 {
                     throw new BundleException(
                         "Exported package names cannot be zero length.");
                 }
             }
-        }
 
-        // If both version and specification-version attributes are specified,
-        // then verify that the values are equal.
-        for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
-        {
             // Check for "version" and "specification-version" attributes
             // and verify they are the same if both are specified.
-            Object v = clauses.get(clauseIdx).m_attrs.get(Constants.VERSION_ATTRIBUTE);
-            Object sv = clauses.get(clauseIdx).m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
+            Object v = clause.m_attrs.get(Constants.VERSION_ATTRIBUTE);
+            Object sv = clause.m_attrs.get(Constants.PACKAGE_SPECIFICATION_VERSION);
             if ((v != null) && (sv != null))
             {
                 // Verify they are equal.
@@ -560,23 +531,20 @@
             if ((v != null) || (sv != null))
             {
                 // Convert version attribute to type Version.
-                clauses.get(clauseIdx).m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
+                clause.m_attrs.remove(Constants.PACKAGE_SPECIFICATION_VERSION);
                 v = (v == null) ? sv : v;
-                clauses.get(clauseIdx).m_attrs.put(
+                clause.m_attrs.put(
                     Constants.VERSION_ATTRIBUTE,
                     Version.parseVersion(v.toString()));
             }
-        }
 
-        // If this is an R4 bundle, then make sure it doesn't specify
-        // bundle symbolic name or bundle version attributes.
-        if (mv.equals("2"))
-        {
-            for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+            // If this is an R4 bundle, then make sure it doesn't specify
+            // bundle symbolic name or bundle version attributes.
+            if (mv.equals("2"))
             {
                 // Find symbolic name and version attribute, if present.
-                if (clauses.get(clauseIdx).m_attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
-                    || clauses.get(clauseIdx).m_attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                if (clause.m_attrs.containsKey(Constants.BUNDLE_VERSION_ATTRIBUTE)
+                    || clause.m_attrs.containsKey(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
                 {
                     throw new BundleException(
                         "Exports must not specify bundle symbolic name or bundle version.");
@@ -584,21 +552,13 @@
 
                 // Now that we know that there are no bundle symbolic name and version
                 // attributes, add them since the spec says they are there implicitly.
-                clauses.get(clauseIdx).m_attrs.put(
-                    Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
-                clauses.get(clauseIdx).m_attrs.put(
-                    Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
+                clause.m_attrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
+                clause.m_attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bv);
             }
-        }
-        else if (!mv.equals("2"))
-        {
-            // Check to make sure that R3 bundles have only specified
-            // the 'specification-version' attribute and no directives
-            // on their exports; ignore all unknown attributes.
-            for (int clauseIdx = 0; clauseIdx < clauses.size(); clauseIdx++)
+            else if (!mv.equals("2"))
             {
                 // R3 bundles cannot have directives on their exports.
-                if (!clauses.get(clauseIdx).m_dirs.isEmpty())
+                if (!clause.m_dirs.isEmpty())
                 {
                     throw new BundleException("R3 exports cannot contain directives.");
                 }
@@ -608,19 +568,16 @@
                 // because the package class normalizes to "version" to avoid having
                 // future special cases. This could be changed if more strict behavior
                 // is required.
-                if (!clauses.get(clauseIdx).m_attrs.isEmpty())
+                if (!clause.m_attrs.isEmpty())
                 {
                     // R3 package capabilities should only have a version attribute.
-                    Map<String, Object> attrs = clauses.get(clauseIdx).m_attrs;
-                    Object pkgVersion = clauses.get(clauseIdx).m_attrs
-                        .get(BundleCapabilityImpl.VERSION_ATTR);
+                    Object pkgVersion = clause.m_attrs.get(BundleCapabilityImpl.VERSION_ATTR);
                     pkgVersion = (pkgVersion == null)
                         ? Version.emptyVersion
                         : pkgVersion;
-                    for (Entry<String, Object> entry : clauses.get(clauseIdx).m_attrs.entrySet())
+                    for (Entry<String, Object> entry : clause.m_attrs.entrySet())
                     {
-                        if (!entry.getKey().equals(
-                            BundleCapabilityImpl.VERSION_ATTR))
+                        if (!entry.getKey().equals(BundleCapabilityImpl.VERSION_ATTR))
                         {
                             logger.log(
                                 Logger.LOG_WARNING,
@@ -629,17 +586,13 @@
                         }
                     }
 
-                    // Recreate the export to remove any other attributes
-                    // and add version if missing.
-                    Map<String, Object> newAttrs = new HashMap<String, Object>(1);
-                    newAttrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
-                    clauses.set(clauseIdx, new ParsedHeaderClause(
-                        clauses.get(clauseIdx).m_paths,
-                        clauses.get(clauseIdx).m_dirs,
-                        newAttrs));
+                    // Remove all other attributes except package version.
+                    clause.m_attrs.clear();
+                    clause.m_attrs.put(BundleCapabilityImpl.VERSION_ATTR, pkgVersion);
                 }
             }
         }
+
         return clauses;
     }
 
@@ -695,11 +648,6 @@
         return m_requirements;
     }
 
-    public List<BundleRequirement> getDynamicRequirements()
-    {
-        return m_dynamicRequirements;
-    }
-
     public List<R4LibraryClause> getLibraryClauses()
     {
         return m_libraryClauses;