You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2018/04/26 10:00:59 UTC

[sling-whiteboard] branch master updated: Use felix utils ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil. As with that the feature-support module is empty, remove it.

This is an automated email from the ASF dual-hosted git repository.

pauls pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ff9e42  Use felix utils ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil. As with that the feature-support module is empty, remove it.
6ff9e42 is described below

commit 6ff9e42b61ba919ca2824c44f53917a0baf7211a
Author: Karl Pauls <kp...@adobe.com>
AuthorDate: Thu Apr 26 12:00:25 2018 +0200

    Use felix utils ResourceBuilder and Parser instead of the ManifestParser and ManifestUtil. As with that the feature-support module is empty, remove it.
---
 featuremodel/feature-analyser/pom.xml              |    8 +-
 .../task/impl/CheckBundleExportsImports.java       |    2 +-
 .../task/impl/CheckRequirementsCapabilities.java   |   35 +-
 .../sling/feature/scanner/BundleDescriptor.java    |    1 -
 .../apache/sling/feature/scanner/Descriptor.java   |    1 -
 .../apache/sling/feature/scanner}/PackageInfo.java |    2 +-
 .../feature/scanner/impl/BundleDescriptorImpl.java |   77 +-
 .../scanner/impl/FelixFrameworkScanner.java        |   76 +-
 .../scanner/impl/BundleDescriptorImplTest.java     |   73 ++
 .../scanner/impl/FelixFrameworkScannerTest.java    |   21 +
 featuremodel/feature-applicationbuilder/pom.xml    |    6 -
 featuremodel/feature-karaf/pom.xml                 |    6 -
 featuremodel/feature-launcher/pom.xml              |    7 +-
 featuremodel/feature-modelconverter/pom.xml        |    6 -
 featuremodel/feature-resolver/pom.xml              |    6 -
 .../feature/resolver/impl/BundleResourceImpl.java  |   33 +-
 .../sling/feature/resolver/AnalyserTest.java       |    1 +
 .../feature/resolver/TestBundleResourceImpl.java   |    2 +-
 .../resolver/impl/BundleResourceImplTest.java      |   46 +-
 featuremodel/feature-support/pom.xml               |  132 ---
 .../feature/support/util/CapabilityMatcher.java    |   34 -
 .../sling/feature/support/util/ManifestParser.java | 1025 --------------------
 .../sling/feature/support/util/ManifestUtil.java   |  175 ----
 .../sling/feature/support/util/SimpleFilter.java   |  650 -------------
 .../feature/support/util/ManifestUtilTest.java     |   43 -
 featuremodel/osgifeature-maven-plugin/pom.xml      |    5 -
 featuremodel/pom.xml                               |    1 -
 27 files changed, 259 insertions(+), 2215 deletions(-)

diff --git a/featuremodel/feature-analyser/pom.xml b/featuremodel/feature-analyser/pom.xml
index a2bca4b..0241695 100644
--- a/featuremodel/feature-analyser/pom.xml
+++ b/featuremodel/feature-analyser/pom.xml
@@ -56,7 +56,7 @@
                         <outputDirectory>${project.build.directory}/classes</outputDirectory>
                         <overWriteReleases>false</overWriteReleases>
                         <overWriteSnapshots>true</overWriteSnapshots>
-                        <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.sling.commons.osgi,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
+                        <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.commons.johnzon,org.apache.sling.commons.osgi,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
                     </configuration>
                 </execution>
             </executions>
@@ -126,12 +126,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
             <version>2.4.0</version>
             <scope>provided</scope>
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
index 0fc5a00..6a44c97 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
@@ -29,7 +29,7 @@ import java.util.TreeMap;
 import org.apache.sling.feature.analyser.task.AnalyserTask;
 import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
 import org.osgi.framework.Version;
 
 public class CheckBundleExportsImports implements AnalyserTask {
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
index daa0a91..bd1732f 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
@@ -22,6 +22,7 @@ import org.apache.sling.feature.analyser.task.AnalyserTask;
 import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
 import org.apache.sling.feature.scanner.ArtifactDescriptor;
 import org.apache.sling.feature.scanner.BundleDescriptor;
+import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.resource.Requirement;
 
 import java.util.ArrayList;
@@ -69,22 +70,30 @@ public class CheckRequirementsCapabilities implements AnalyserTask {
                 if (info.getRequirements() != null)
                 {
                     for (Requirement requirement : info.getRequirements()) {
-                        List<ArtifactDescriptor> candidates = getCandidates(artifacts, requirement);
+                        if (!BundleRevision.PACKAGE_NAMESPACE.equals(requirement.getNamespace()))
+                        {
+                            List<ArtifactDescriptor> candidates = getCandidates(artifacts, requirement);
 
-                        if (candidates.isEmpty()) {
-                            if ( "osgi.service".equals(requirement.getNamespace())  ){
-                                // osgi.service is special - we don't provide errors or warnings in this case
-                                continue;
+                            if (candidates.isEmpty())
+                            {
+                                if ("osgi.service".equals(requirement.getNamespace()))
+                                {
+                                    // osgi.service is special - we don't provide errors or warnings in this case
+                                    continue;
+                                }
+                                if (!RequirementImpl.isOptional(requirement))
+                                {
+                                    ctx.reportError(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "no artifact is providing a matching capability in this start level."));
+                                }
+                                else
+                                {
+                                    ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "while the requirement is optional no artifact is providing a matching capability in this start level."));
+                                }
                             }
-                            if (!RequirementImpl.isOptional(requirement)) {
-                                ctx.reportError(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "no artifact is providing a matching capability in this start level."));
+                            else if (candidates.size() > 1)
+                            {
+                                ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "there is more than one matching capability in this start level."));
                             }
-                            else {
-                                ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "while the requirement is optional no artifact is providing a matching capability in this start level."));
-                            }
-                        }
-                        else if ( candidates.size() > 1 ) {
-                            ctx.reportWarning(String.format(format, info.getArtifact().getId().getArtifactId(), info.getArtifact().getId().getVersion(), requirement.toString(), entry.getKey(), "there is more than one matching capability in this start level."));
                         }
                     }
                 }
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
index 748bec9..52f3a71 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
@@ -19,7 +19,6 @@ package org.apache.sling.feature.scanner;
 import java.util.jar.Manifest;
 
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.util.PackageInfo;
 
 /**
  * Information about a bundle
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
index a97cda0..2b5fc1b 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
@@ -20,7 +20,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.apache.sling.feature.support.util.PackageInfo;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
similarity index 98%
rename from featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java
rename to featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
index 725906d..bb7081b 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/PackageInfo.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.feature.support.util;
+package org.apache.sling.feature.scanner;
 
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
index 2f2c54b..d93b89c 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
@@ -18,14 +18,21 @@ package org.apache.sling.feature.scanner.impl;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
+import java.util.jar.JarFile;
 import java.util.jar.Manifest;
+import java.util.stream.Collectors;
 
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.resource.ResourceBuilder;
+import org.apache.felix.utils.resource.ResourceImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.ManifestParser;
-import org.apache.sling.feature.support.util.ManifestUtil;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
 import org.osgi.framework.Constants;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
@@ -60,8 +67,9 @@ public class BundleDescriptorImpl
         this.artifact = a;
         this.artifactFile = file;
         this.startLevel = startLevel;
-
-        this.manifest = ManifestUtil.getManifest(file);
+        try (final JarFile jarFile = new JarFile(this.artifactFile) ) {
+            this.manifest = jarFile.getManifest();
+        }
         if ( this.manifest == null ) {
             throw new IOException("File has no manifest");
         }
@@ -142,13 +150,14 @@ public class BundleDescriptorImpl
                 this.symbolicName = newBundleName;
             }
 
-            this.getExportedPackages().addAll(ManifestUtil.extractExportedPackages(this.manifest));
-            this.getImportedPackages().addAll(ManifestUtil.extractImportedPackages(this.manifest));
-            this.getDynamicImportedPackages().addAll(ManifestUtil.extractDynamicImportedPackages(this.manifest));
+            this.getExportedPackages().addAll(extractExportedPackages(this.manifest));
+            this.getImportedPackages().addAll(extractImportedPackages(this.manifest));
+            this.getDynamicImportedPackages().addAll(extractDynamicImportedPackages(this.manifest));
             try {
-                ManifestParser parser = new ManifestParser(this.manifest);
-                this.getCapabilities().addAll(ManifestUtil.extractCapabilities(parser));
-                this.getRequirements().addAll(ManifestUtil.extractRequirements(parser));
+                ResourceImpl resource = ResourceBuilder.build(null, this.manifest.getMainAttributes().entrySet().stream()
+                    .collect(Collectors.toMap(entry -> entry.getKey().toString(), entry -> entry.getValue().toString())));
+                this.getCapabilities().addAll(resource.getCapabilities(null));
+                this.getRequirements().addAll(resource.getRequirements(null));
             } catch (Exception ex) {
                 throw new IOException(ex);
             }
@@ -156,4 +165,50 @@ public class BundleDescriptorImpl
             throw new IOException("Unable to get bundle symbolic name from artifact " + getArtifact().getId().toMvnId());
         }
     }
+
+    public static List<PackageInfo> extractPackages(final Manifest m,
+        final String headerName,
+        final String defaultVersion,
+        final boolean checkOptional) {
+        final String pckInfo = m.getMainAttributes().getValue(headerName);
+        if (pckInfo != null) {
+            final Clause[] clauses = Parser.parseHeader(pckInfo);
+
+            final List<PackageInfo> pcks = new ArrayList<>();
+            for(final Clause entry : clauses) {
+                Object versionObj = entry.getAttribute("version");
+                final String version;
+                if ( versionObj == null ) {
+                    version = defaultVersion;
+                } else {
+                    version = versionObj.toString();
+                }
+
+                boolean optional = false;
+                if ( checkOptional ) {
+                    final String resolution = entry.getDirective("resolution");
+                    optional = "optional".equalsIgnoreCase(resolution);
+                }
+                final PackageInfo pck = new PackageInfo(entry.getName(),
+                    version,
+                    optional);
+                pcks.add(pck);
+            }
+
+            return pcks;
+        }
+        return Collections.emptyList();
+    }
+
+    public static List<PackageInfo> extractExportedPackages(final Manifest m) {
+        return extractPackages(m, Constants.EXPORT_PACKAGE, "0.0.0", false);
+    }
+
+    public static List<PackageInfo> extractImportedPackages(final Manifest m) {
+        return extractPackages(m, Constants.IMPORT_PACKAGE, null, true);
+    }
+
+    public static List<PackageInfo> extractDynamicImportedPackages(final Manifest m) {
+        return extractPackages(m, Constants.DYNAMICIMPORT_PACKAGE, null, false);
+    }
 }
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
index 14644d2..2bb2cde 100644
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
+++ b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
@@ -16,15 +16,12 @@
  */
 package org.apache.sling.feature.scanner.impl;
 
-import static org.apache.sling.feature.support.util.ManifestParser.convertProvideCapabilities;
-import static org.apache.sling.feature.support.util.ManifestParser.normalizeCapabilityClauses;
-import static org.apache.sling.feature.support.util.ManifestParser.parseStandardHeader;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Properties;
@@ -37,14 +34,14 @@ import java.util.zip.ZipInputStream;
 
 import org.apache.commons.lang.text.StrLookup;
 import org.apache.commons.lang.text.StrSubstitutor;
-import org.apache.sling.commons.osgi.ManifestHeader;
+import org.apache.felix.utils.manifest.Parser;
+import org.apache.felix.utils.resource.ResourceBuilder;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.KeyValueMap;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.spi.FrameworkScanner;
-import org.apache.sling.feature.support.util.PackageInfo;
-import org.osgi.framework.BundleException;
+import org.apache.sling.feature.scanner.PackageInfo;
 import org.osgi.framework.Constants;
 import org.osgi.resource.Capability;
 
@@ -61,7 +58,7 @@ public class FelixFrameworkScanner implements FrameworkScanner {
             return null;
         }
         final Set<PackageInfo> pcks = calculateSystemPackages(fwkProps);
-        final Set<Capability> capabilities = calculateSystemCapabilities(fwkProps);
+        final List<Capability> capabilities = calculateSystemCapabilities(fwkProps);
 
         final BundleDescriptor d = new BundleDescriptor() {
 
@@ -101,44 +98,45 @@ public class FelixFrameworkScanner implements FrameworkScanner {
         return d;
     }
 
-    private Set<Capability> calculateSystemCapabilities(final KeyValueMap fwkProps) {
-        return Stream.of(
+    private List<Capability> calculateSystemCapabilities(final KeyValueMap fwkProps) throws IOException
+    {
+         Map<String, String> mf = new HashMap<>();
+         mf.put(Constants.PROVIDE_CAPABILITY,
+                Stream.of(
                     fwkProps.get(Constants.FRAMEWORK_SYSTEMCAPABILITIES),
                     fwkProps.get(Constants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA)
                 )
                 .filter(Objects::nonNull)
-                .flatMap(header -> {
-                        try {
-                            return convertProvideCapabilities(normalizeCapabilityClauses(parseStandardHeader(header), "2"))
-                                    .stream();
-                        } catch (BundleException ex) {
-                            throw new RuntimeException(ex);
-                        }
-                    })
-                .collect(Collectors.toSet());
+                .collect(Collectors.joining(",")));
+         mf.put(Constants.EXPORT_PACKAGE, Stream.of(
+             fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES),
+             fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA)
+             ).filter(Objects::nonNull)
+                 .collect(Collectors.joining(",")));
+         mf.put(Constants.BUNDLE_SYMBOLICNAME, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
+         mf.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+         try
+         {
+             return ResourceBuilder.build(null, mf).getCapabilities(null);
+         }
+         catch (Exception ex) {
+             throw new IOException(ex);
+         }
     }
 
     private Set<PackageInfo> calculateSystemPackages(final KeyValueMap fwkProps) {
-        final String system = fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES);
-        final String extra = fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
-        final Set<PackageInfo> packages = new HashSet<>();
-        for(int i=0;i<2;i++) {
-            final String value = (i == 0 ? system : extra);
-            if ( value != null ) {
-                final ManifestHeader header = ManifestHeader.parse(value);
-                for(final ManifestHeader.Entry entry : header.getEntries()) {
-                    String version = entry.getAttributeValue("version");
-                    if ( version == null ) {
-                        version = "0.0.0";
-                    }
-
-                    final PackageInfo exportedPackageInfo = new PackageInfo(entry.getValue(),
-                            version, false);
-                    packages.add(exportedPackageInfo);
-                }
-            }
-        }
-        return packages;
+        return
+            Stream.of(
+                Parser.parseHeader(
+                    Stream.of(
+                        fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES),
+                        fwkProps.get(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA)
+                    ).filter(Objects::nonNull)
+                    .collect(Collectors.joining(","))
+                )
+            ).map(
+                clause -> new PackageInfo(clause.getName(), clause.getAttribute("version") != null ? clause.getAttribute("version") : "0.0.0", false))
+            .collect(Collectors.toSet());
     }
 
     private static final String DEFAULT_PROPERTIES = "default.properties";
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
new file mode 100644
index 0000000..a8d289c
--- /dev/null
+++ b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.sling.feature.scanner.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.scanner.PackageInfo;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+public class BundleDescriptorImplTest
+{
+
+    private void assertPackageInfo(Set<PackageInfo> infos, final String name, final Version version) {
+        for (PackageInfo info : infos)
+        {
+            if (name.equals(info.getName()) && version.equals(info.getPackageVersion()))
+            {
+                return;
+            }
+        }
+        fail();
+    }
+
+    @Test public void testExportPackage() throws Exception {
+        String bmf = "Bundle-SymbolicName: pkg.bundle\n"
+            + "Bundle-Version: 1\n"
+            + "Bundle-ManifestVersion: 2\n"
+            + "Export-Package: org.apache.sling;version=1.0,org.apache.felix;version=2.0\n";
+        File f = createBundle(bmf);
+        BundleDescriptorImpl bdf = new BundleDescriptorImpl(new Artifact(new ArtifactId("foo", "bar", "1.0", "bla", "bundle")), f, 1);
+        final Set<PackageInfo> infos = bdf.getExportedPackages();
+        assertEquals(2, infos.size());
+        assertPackageInfo(infos ,"org.apache.sling", Version.parseVersion("1.0"));
+        assertPackageInfo(infos,"org.apache.felix", Version.parseVersion("2.0"));
+    }
+
+    private File createBundle(String manifest) throws IOException
+    {
+        File f = File.createTempFile("bundle", ".jar");
+        f.deleteOnExit();
+        Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("UTF-8")));
+        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+        os.close();
+        return f;
+    }
+}
diff --git a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
index 7e0d02f..d5edc80 100644
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
+++ b/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
@@ -16,13 +16,18 @@
  */
 package org.apache.sling.feature.scanner.impl;
 
+import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.KeyValueMap;
+import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.junit.Test;
 
 import java.io.File;
 import java.net.URL;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class FelixFrameworkScannerTest {
     @Test
@@ -46,4 +51,20 @@ public class FelixFrameworkScannerTest {
                 + "osgi.ee; osgi.ee=\"JavaSE/compact2\"; version:List<Version>=\"1.8\", "
                 + "osgi.ee; osgi.ee=\"JavaSE/compact3\"; version:List<Version>=\"1.8\" ", props.get("org.osgi.framework.system.capabilities"));
     }
+
+    @Test
+    public void testGetFrameworkExports() throws Exception {
+        URL url = getClass().getResource("/test-framework.jar");
+        File fwFile = new File(url.toURI());
+
+        FelixFrameworkScanner ffs = new FelixFrameworkScanner();
+
+        KeyValueMap kvmap = new KeyValueMap();
+        BundleDescriptor bundleDescriptor = ffs.scan(new ArtifactId("org.apache.felix",
+            "org.apache.felix.framework",
+            "5.6.10", null, null), fwFile, kvmap);
+
+        assertFalse(bundleDescriptor.getExportedPackages().isEmpty());
+        assertFalse(bundleDescriptor.getCapabilities().isEmpty());
+    }
 }
diff --git a/featuremodel/feature-applicationbuilder/pom.xml b/featuremodel/feature-applicationbuilder/pom.xml
index 3cb9e08..cc16c11 100644
--- a/featuremodel/feature-applicationbuilder/pom.xml
+++ b/featuremodel/feature-applicationbuilder/pom.xml
@@ -122,12 +122,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.johnzon</artifactId>
             <version>1.0.0</version>
             <scope>provided</scope>
diff --git a/featuremodel/feature-karaf/pom.xml b/featuremodel/feature-karaf/pom.xml
index 315afec..6204869 100644
--- a/featuremodel/feature-karaf/pom.xml
+++ b/featuremodel/feature-karaf/pom.xml
@@ -74,11 +74,5 @@
             <version>0.0.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
     </dependencies>
 </project>
diff --git a/featuremodel/feature-launcher/pom.xml b/featuremodel/feature-launcher/pom.xml
index a71522d..fdcd201 100644
--- a/featuremodel/feature-launcher/pom.xml
+++ b/featuremodel/feature-launcher/pom.xml
@@ -55,7 +55,7 @@
                         <outputDirectory>${project.build.directory}/classes</outputDirectory>
                         <overWriteReleases>false</overWriteReleases>
                         <overWriteSnapshots>true</overWriteSnapshots>
-                        <includeArtifactIds>org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple,osgi.core</includeArtifactIds>
+                        <includeArtifactIds>org.apache.sling.feature,org.apache.sling.commons.johnzon,org.apache.felix.converter,commons-cli,slf4j-api,slf4j-simple,osgi.core</includeArtifactIds>
                     </configuration>
                 </execution>
             </executions>
@@ -111,11 +111,6 @@
             <version>0.0.1-SNAPSHOT</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.converter</artifactId>
             <version>0.1.0-SNAPSHOT</version>
diff --git a/featuremodel/feature-modelconverter/pom.xml b/featuremodel/feature-modelconverter/pom.xml
index 8386c38..62547a1 100644
--- a/featuremodel/feature-modelconverter/pom.xml
+++ b/featuremodel/feature-modelconverter/pom.xml
@@ -143,12 +143,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.provisioning.model</artifactId>
             <version>1.8.2</version>
             <scope>provided</scope>
diff --git a/featuremodel/feature-resolver/pom.xml b/featuremodel/feature-resolver/pom.xml
index c52badb..d320ce2 100644
--- a/featuremodel/feature-resolver/pom.xml
+++ b/featuremodel/feature-resolver/pom.xml
@@ -80,12 +80,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
             <version>2.4.0</version>
             <scope>provided</scope>
diff --git a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
index 901b141..e196145 100644
--- a/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/main/java/org/apache/sling/feature/resolver/impl/BundleResourceImpl.java
@@ -22,7 +22,7 @@ import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.resolver.FeatureResource;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
 import org.osgi.framework.namespace.BundleNamespace;
@@ -69,18 +69,6 @@ public class BundleResourceImpl extends AbstractResourceImpl implements FeatureR
             l.add(new CapabilityImpl(this, c));
         }
 
-        // Add the package capabilities (export package)
-        List<Capability> pkgCaps = new ArrayList<>();
-        for(PackageInfo exported : bd.getExportedPackages()) {
-            Map<String, Object> attrs = new HashMap<>();
-            attrs.put(PackageNamespace.PACKAGE_NAMESPACE, exported.getName());
-            attrs.put(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, exported.getPackageVersion());
-            attrs.put(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE, bsn);
-            attrs.put(PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, version);
-            pkgCaps.add(new CapabilityImpl(this, PackageNamespace.PACKAGE_NAMESPACE, null, attrs));
-        }
-        caps.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgCaps));
-
         // Add the identity capability
         Map<String, Object> idattrs = new HashMap<>();
         idattrs.put(IdentityNamespace.IDENTITY_NAMESPACE, bsn);
@@ -111,25 +99,6 @@ public class BundleResourceImpl extends AbstractResourceImpl implements FeatureR
         // TODO What do we do with the execution environment?
         reqs.remove(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
 
-        // Add the package requirements (import package)
-        List<Requirement> pkgReqs = new ArrayList<>();
-        for(PackageInfo imported : bd.getImportedPackages()) {
-            Map<String, String> dirs = new HashMap<>();
-            VersionRange range = imported.getPackageVersionRange();
-            String rangeFilter;
-            if (range != null) {
-                rangeFilter = range.toFilterString(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
-            } else {
-                rangeFilter = "";
-            }
-            dirs.put(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE,
-                "(&(" + PackageNamespace.PACKAGE_NAMESPACE + "=" + imported.getName() + ")" + rangeFilter + ")");
-            if (imported.isOptional())
-                dirs.put(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE,
-                    PackageNamespace.RESOLUTION_OPTIONAL);
-            pkgReqs.add(new RequirementImpl(this, PackageNamespace.PACKAGE_NAMESPACE, dirs, null));
-        }
-        reqs.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgReqs));
         requirements = Collections.unmodifiableMap(reqs);
     }
 
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
index c4b8110..527eec5 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/AnalyserTest.java
@@ -27,6 +27,7 @@ import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.Scanner;
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.File;
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
index 86beec4..265aa21 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/TestBundleResourceImpl.java
@@ -21,7 +21,7 @@ import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
 import org.osgi.framework.Version;
 import org.osgi.framework.VersionRange;
 import org.osgi.framework.namespace.BundleNamespace;
diff --git a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
index eb307d2..c829958 100644
--- a/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
+++ b/featuremodel/feature-resolver/src/test/java/org/apache/sling/feature/resolver/impl/BundleResourceImplTest.java
@@ -25,9 +25,11 @@ import org.apache.sling.feature.resolver.FeatureResource;
 import org.apache.sling.feature.scanner.BundleDescriptor;
 import org.apache.sling.feature.scanner.Descriptor;
 import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.support.util.PackageInfo;
+import org.apache.sling.feature.scanner.PackageInfo;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mockito;
+import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.namespace.BundleNamespace;
 import org.osgi.framework.namespace.PackageNamespace;
@@ -35,6 +37,10 @@ import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.Collections;
@@ -43,6 +49,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -95,17 +103,17 @@ public class BundleResourceImplTest {
         ArtifactId id = new ArtifactId("grp", "art", "1.2.3", null, null);
         Artifact artifact = new Artifact(id);
 
-        PackageInfo ex1 = new PackageInfo("org.foo.a", "0.0.1.SNAPSHOT", false);
-        Set<PackageInfo> pkgs = Collections.singleton(ex1);
-        Set<Requirement> reqs = Collections.emptySet();
-        Set<Capability> caps = Collections.emptySet();
-        BundleDescriptor bd = new BundleDescriptorImpl(artifact, pkgs, reqs, caps);
+        String bmf = "Bundle-SymbolicName: " + Constants.SYSTEM_BUNDLE_SYMBOLICNAME + "\n"
+            + "Bundle-Version: 1.2.3\n"
+            + "Bundle-ManifestVersion: 2\n"
+            + "Export-Package: org.foo.a;version=0.0.1.SNAPSHOT\n"
+            + "Import-Package: org.bar;version=\"[1,2)\",org.tar;resolution:=\"optional\"\n";
+
+        File f = createBundle(bmf);
+
+
+        BundleDescriptor bd = new BundleDescriptorImpl(artifact, f, 1);
 
-        setField(Descriptor.class, "locked", bd, false); // Unlock the Bundle Descriptor for the test
-        PackageInfo im1 = new PackageInfo("org.bar", "[1,2)", false);
-        PackageInfo im2 = new PackageInfo("org.tar", null, true);
-        bd.getImportedPackages().add(im1);
-        bd.getImportedPackages().add(im2);
 
         Resource res = new BundleResourceImpl(bd, null);
         assertNotNull(
@@ -137,11 +145,11 @@ public class BundleResourceImplTest {
         }
 
         assertEquals(1, reqBar.getDirectives().size());
-        assertEquals("(&(osgi.wiring.package=org.bar)(&(version>=1.0.0)(!(version>=2.0.0))))",
+        assertEquals("(&(osgi.wiring.package=org.bar)(version>=1.0.0)(!(version>=2.0.0)))",
                 reqBar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE));
 
         assertEquals(2, reqTar.getDirectives().size());
-        assertEquals("(&(osgi.wiring.package=org.tar))",
+        assertEquals("(osgi.wiring.package=org.tar)",
                 reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE));
         assertEquals(PackageNamespace.RESOLUTION_OPTIONAL,
                 reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
@@ -185,6 +193,18 @@ public class BundleResourceImplTest {
                 new HashSet<>(res.getRequirements(null)));
     }
 
+
+    private File createBundle(String manifest) throws IOException
+    {
+        File f = File.createTempFile("bundle", ".jar");
+        f.deleteOnExit();
+        Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("UTF-8")));
+        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+        os.close();
+        return f;
+    }
+
     private Object getCapAttribute(Resource res, String ns, String attr) {
         List<Capability> caps = res.getCapabilities(ns);
         if (caps.size() == 0)
diff --git a/featuremodel/feature-support/pom.xml b/featuremodel/feature-support/pom.xml
deleted file mode 100644
index 97b9729..0000000
--- a/featuremodel/feature-support/pom.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-    <!--
-        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">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>33</version>
-        <relativePath />
-    </parent>
-
-    <artifactId>org.apache.sling.feature.support</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <packaging>bundle</packaging>
-    
-    <name>Apache Sling Feature Support</name>
-    <description>
-        Support classes for the feature tools
-    </description>
-
-    <properties>
-        <sling.java.version>8</sling.java.version>
-    </properties>
-
-    <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-support</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-support</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-support</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                        <Conditional-Package>
-                            org.apache.felix.configurator.impl.json,
-                            org.apache.felix.configurator.impl.model                            
-                        </Conditional-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.annotation.versioning</artifactId>
-            <version>1.0.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>osgi.core</artifactId>
-            <version>6.0.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.io</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.converter</artifactId>
-            <version>0.1.0-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.configurator</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.utils</artifactId>
-            <version>1.11.0-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-json_1.0_spec</artifactId>
-            <version>1.0-alpha-1</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- Testing -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <version>2.8.9</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.johnzon</groupId>
-            <artifactId>johnzon-core</artifactId>
-            <version>1.0.0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java
deleted file mode 100644
index 3c574a2..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/CapabilityMatcher.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.support.util;
-
-import org.apache.felix.utils.resource.CapabilitySet;
-import org.osgi.resource.Capability;
-
-
-public class CapabilityMatcher
-{
-    static boolean matches(Capability cap, SimpleFilter sf)
-    {
-        // Translate the SimpleFilter into the one from Felix Utils.
-        // Once the SimpleFilter has moved to Felix Utils, this class can be removed.
-        org.apache.felix.utils.resource.SimpleFilter sf2 =
-                org.apache.felix.utils.resource.SimpleFilter.parse(sf.toString());
-
-        return CapabilitySet.matches(cap, sf2);
-    }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java
deleted file mode 100644
index 1da64ab..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestParser.java
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.support.util;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-import org.osgi.framework.namespace.BundleNamespace;
-import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.jar.Manifest;
-
-public class ManifestParser {
-
-    private final Manifest m_headerMap;
-    private volatile String m_bundleSymbolicName;
-    private volatile Version m_bundleVersion;
-    private volatile List<Capability> m_capabilities;
-    private volatile List<Requirement> m_requirements;
-
-    public ManifestParser(Manifest m)
-            throws BundleException
-    {
-        m_headerMap = m;
-
-        // Verify that only manifest version 2 is specified.
-        String manifestVersion = getManifestVersion(m_headerMap);
-        if ((manifestVersion != null) && !manifestVersion.equals("2"))
-        {
-            throw new BundleException(
-                    "Unknown 'Bundle-ManifestVersion' value: " + manifestVersion);
-        }
-
-        List<Capability> capList = new ArrayList<>();
-
-        //
-        // Parse bundle version.
-        //
-
-        m_bundleVersion = Version.emptyVersion;
-        if (m_headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION) != null)
-        {
-            try
-            {
-                m_bundleVersion = Version.parseVersion(m_headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
-            }
-            catch (RuntimeException ex)
-            {
-                // R4 bundle versions must parse, R3 bundle version may not.
-                if (getManifestVersion().equals("2"))
-                {
-                    throw ex;
-                }
-                m_bundleVersion = Version.emptyVersion;
-            }
-        }
-
-        //
-        // Parse bundle symbolic name.
-        //
-
-        Capability bundleCap = parseBundleSymbolicName(m_headerMap);
-        if (bundleCap != null)
-        {
-            m_bundleSymbolicName = (String)
-                    bundleCap.getAttributes().get(BundleRevision.BUNDLE_NAMESPACE);
-
-            // Add a bundle capability and a host capability to all
-            // non-fragment bundles. A host capability is the same
-            // as a require capability, but with a different capability
-            // namespace. Bundle capabilities resolve required-bundle
-            // dependencies, while host capabilities resolve fragment-host
-            // dependencies.
-            if (m_headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) == null)
-            {
-                // All non-fragment bundles have host capabilities.
-                capList.add(bundleCap);
-                // A non-fragment bundle can choose to not have a host capability.
-                String attachment =
-                        bundleCap.getDirectives().get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
-                attachment = (attachment == null)
-                        ? Constants.FRAGMENT_ATTACHMENT_RESOLVETIME
-                        : attachment;
-                if (!attachment.equalsIgnoreCase(Constants.FRAGMENT_ATTACHMENT_NEVER))
-                {
-                    Map<String, Object> hostAttrs =
-                            new HashMap<>(bundleCap.getAttributes());
-                    Object value = hostAttrs.remove(BundleRevision.BUNDLE_NAMESPACE);
-                    hostAttrs.put(BundleRevision.HOST_NAMESPACE, value);
-                    Capability cap = new CapabilityImpl(null, BundleRevision.HOST_NAMESPACE, bundleCap.getDirectives(), hostAttrs);
-                    capList.add(cap);
-                }
-            }
-
-            //
-            // Add the osgi.identity capability.
-            //
-            capList.add(addIdentityCapability(m_headerMap, bundleCap));
-        }
-
-        // Verify that bundle symbolic name is specified.
-        if (getManifestVersion().equals("2") && (m_bundleSymbolicName == null))
-        {
-            throw new BundleException(
-                    "R4 bundle manifests must include bundle symbolic name.");
-        }
-
-        //
-        // Parse Fragment-Host.
-        //
-
-        List<Requirement> hostReqs = parseFragmentHost(m_headerMap);
-
-        //
-        // Parse Require-Bundle
-        //
-
-        List<ParsedHeaderClause> rbClauses =
-                parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.REQUIRE_BUNDLE));
-        rbClauses = normalizeRequireClauses(rbClauses, getManifestVersion());
-        List<Requirement> rbReqs = convertRequires(rbClauses);
-
-
-        //
-        // Parse Require-Capability.
-        //
-
-        List<ParsedHeaderClause> requireClauses =
-                parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.REQUIRE_CAPABILITY));
-        List<Requirement> requireReqs = convertRequireCapabilities(normalizeCapabilityClauses( requireClauses, getManifestVersion()));
-
-        //
-        // Parse Provide-Capability.
-        //
-
-        List<ParsedHeaderClause> provideClauses =
-                parseStandardHeader(m_headerMap.getMainAttributes().getValue(Constants.PROVIDE_CAPABILITY));
-
-        List<Capability> provideCaps = convertProvideCapabilities(normalizeCapabilityClauses(provideClauses, getManifestVersion()));
-
-        // Combine all requirements.
-        m_requirements = new ArrayList<>();
-        m_requirements.addAll(hostReqs);
-        m_requirements.addAll(rbReqs);
-        m_requirements.addAll(requireReqs);
-
-        // Combine all capabilities.
-        m_capabilities = new ArrayList<>();
-        m_capabilities.addAll(capList);
-        m_capabilities.addAll(provideCaps);
-    }
-
-
-    public static List<Requirement> convertRequireCapabilities(
-            List<ParsedHeaderClause> clauses)
-            throws BundleException
-    {
-        // Now convert generic header clauses into requirements.
-        List<Requirement> reqList = new ArrayList<>();
-        for (ParsedHeaderClause clause : clauses)
-        {
-            for (String path : clause.m_paths)
-            {
-                if (path.startsWith("osgi.wiring."))
-                {
-                    throw new BundleException("Manifest cannot use Require-Capability for '"
-                            + path
-                            + "' namespace.");
-                }
-
-                Requirement req = new RequirementImpl(null, path, clause.m_dirs, clause.m_attrs);
-                // Create requirement and add to requirement list.
-                reqList.add(req);
-            }
-        }
-
-        return reqList;
-    }
-
-    public static List<ParsedHeaderClause> normalizeCapabilityClauses(
-            List<ParsedHeaderClause> clauses, String mv)
-            throws BundleException
-    {
-
-        if (!mv.equals("2") && !clauses.isEmpty())
-        {
-            // Should we error here if we are not an R4 bundle?
-        }
-
-        // Convert attributes into specified types.
-        for (ParsedHeaderClause clause : clauses)
-        {
-            for (Entry<String, String> entry : clause.m_types.entrySet())
-            {
-                String type = entry.getValue();
-                if (!type.equals("String"))
-                {
-                    if (type.equals("Double"))
-                    {
-                        clause.m_attrs.put(
-                                entry.getKey(),
-                                new Double(clause.m_attrs.get(entry.getKey()).toString().trim()));
-                    }
-                    else if (type.equals("Version"))
-                    {
-                        clause.m_attrs.put(
-                                entry.getKey(),
-                                new Version(clause.m_attrs.get(entry.getKey()).toString().trim()));
-                    }
-                    else if (type.equals("Long"))
-                    {
-                        clause.m_attrs.put(
-                                entry.getKey(),
-                                new Long(clause.m_attrs.get(entry.getKey()).toString().trim()));
-                    }
-                    else if (type.startsWith("List"))
-                    {
-                        int startIdx = type.indexOf('<');
-                        int endIdx = type.indexOf('>');
-                        if (((startIdx > 0) && (endIdx <= startIdx))
-                                || ((startIdx < 0) && (endIdx > 0)))
-                        {
-                            throw new BundleException(
-                                    "Invalid Provide-Capability attribute list type for '"
-                                            + entry.getKey()
-                                            + "' : "
-                                            + type);
-                        }
-
-                        String listType = "String";
-                        if (endIdx > startIdx)
-                        {
-                            listType = type.substring(startIdx + 1, endIdx).trim();
-                        }
-
-                        List<String> tokens = parseDelimitedString(
-                                clause.m_attrs.get(entry.getKey()).toString(), ",", false);
-                        List<Object> values = new ArrayList<>(tokens.size());
-                        for (String token : tokens)
-                        {
-                            if (listType.equals("String"))
-                            {
-                                values.add(token);
-                            }
-                            else if (listType.equals("Double"))
-                            {
-                                values.add(new Double(token.trim()));
-                            }
-                            else if (listType.equals("Version"))
-                            {
-                                values.add(new Version(token.trim()));
-                            }
-                            else if (listType.equals("Long"))
-                            {
-                                values.add(new Long(token.trim()));
-                            }
-                            else
-                            {
-                                throw new BundleException(
-                                        "Unknown Provide-Capability attribute list type for '"
-                                                + entry.getKey()
-                                                + "' : "
-                                                + type);
-                            }
-                        }
-                        clause.m_attrs.put(
-                                entry.getKey(),
-                                values);
-                    }
-                    else
-                    {
-                        throw new BundleException(
-                                "Unknown Provide-Capability attribute type for '"
-                                        + entry.getKey()
-                                        + "' : "
-                                        + type);
-                    }
-                }
-            }
-        }
-
-        return clauses;
-    }
-
-    public static List<Capability> convertProvideCapabilities(
-            List<ParsedHeaderClause> clauses)
-            throws BundleException
-    {
-        List<Capability> capList = new ArrayList<>();
-        for (ParsedHeaderClause clause : clauses)
-        {
-            for (String path : clause.m_paths)
-            {
-                if (path.startsWith("osgi.wiring."))
-                {
-                    throw new BundleException("Manifest cannot use Provide-Capability for '"
-                            + path
-                            + "' namespace.");
-                }
-
-                Capability capability = new CapabilityImpl(null, path, clause.m_dirs, clause.m_attrs);
-                // Create package capability and add to capability list.
-                capList.add(capability);
-            }
-        }
-
-        return capList;
-    }
-
-
-    public String getManifestVersion()
-    {
-        String manifestVersion = getManifestVersion(m_headerMap);
-        return (manifestVersion == null) ? "1" : manifestVersion;
-    }
-
-    private static String getManifestVersion(Manifest headerMap)
-    {
-        String manifestVersion = headerMap.getMainAttributes().getValue(Constants.BUNDLE_MANIFESTVERSION);
-        return (manifestVersion == null) ? null : manifestVersion.trim();
-    }
-
-    public String getSymbolicName()
-    {
-        return m_bundleSymbolicName;
-    }
-
-    public Version getBundleVersion()
-    {
-        return m_bundleVersion;
-    }
-
-    public List<Capability> getCapabilities()
-    {
-        return m_capabilities;
-    }
-
-    public List<Requirement> getRequirements()
-    {
-        return m_requirements;
-    }
-
-
-    static class ParsedHeaderClause
-    {
-        public final List<String> m_paths;
-        public final Map<String, String> m_dirs;
-        public final Map<String, Object> m_attrs;
-        public final Map<String, String> m_types;
-
-        public ParsedHeaderClause(
-                List<String> paths, Map<String, String> dirs, Map<String, Object> attrs,
-                Map<String, String> types)
-        {
-            m_paths = paths;
-            m_dirs = dirs;
-            m_attrs = attrs;
-            m_types = types;
-        }
-    }
-
-    private static Capability parseBundleSymbolicName(
-            Manifest headerMap)
-            throws BundleException
-    {
-        List<ParsedHeaderClause> clauses = parseStandardHeader(headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
-        if (clauses.size() > 0)
-        {
-            if (clauses.size() > 1)
-            {
-                throw new BundleException(
-                        "Cannot have multiple symbolic names: "
-                                + headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
-            }
-            else if (clauses.get(0).m_paths.size() > 1)
-            {
-                throw new BundleException(
-                        "Cannot have multiple symbolic names: "
-                                + headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
-            }
-
-            // Get bundle version.
-            Version bundleVersion = Version.emptyVersion;
-            if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION) != null)
-            {
-                try
-                {
-                    bundleVersion = Version.parseVersion(
-                            headerMap.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
-                }
-                catch (RuntimeException ex)
-                {
-                    // R4 bundle versions must parse, R3 bundle version may not.
-                    String mv = getManifestVersion(headerMap);
-                    if (mv != null)
-                    {
-                        throw ex;
-                    }
-                    bundleVersion = Version.emptyVersion;
-                }
-            }
-
-            // Create a require capability and return it.
-            String symName = clauses.get(0).m_paths.get(0);
-            clauses.get(0).m_attrs.put(BundleRevision.BUNDLE_NAMESPACE, symName);
-            clauses.get(0).m_attrs.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersion);
-            Capability cap = new CapabilityImpl(null, BundleRevision.BUNDLE_NAMESPACE, clauses.get(0).m_dirs, clauses.get(0).m_attrs);
-
-            return cap;
-        }
-
-        return null;
-    }
-
-    private static Capability addIdentityCapability(Manifest headerMap, Capability bundleCap)
-    {
-        Map<String, Object> attrs = new HashMap<>();
-
-        attrs.put(IdentityNamespace.IDENTITY_NAMESPACE,
-                bundleCap.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE));
-        attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
-                headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) == null
-                        ? IdentityNamespace.TYPE_BUNDLE
-                        : IdentityNamespace.TYPE_FRAGMENT);
-        attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE,
-                bundleCap.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE));
-
-        if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_COPYRIGHT) != null)
-        {
-            attrs.put(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE,
-                    headerMap.getMainAttributes().getValue(Constants.BUNDLE_COPYRIGHT));
-        }
-
-        if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION) != null)
-        {
-            attrs.put(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE,
-                    headerMap.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION));
-        }
-        if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_DOCURL) != null)
-        {
-            attrs.put(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE,
-                    headerMap.getMainAttributes().getValue(Constants.BUNDLE_DOCURL));
-        }
-        if (headerMap.getMainAttributes().getValue(Constants.BUNDLE_LICENSE) != null)
-        {
-            attrs.put(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE,
-                    headerMap.getMainAttributes().getValue(Constants.BUNDLE_LICENSE));
-        }
-
-        Map<String, String> dirs;
-        if (bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE) != null)
-        {
-            dirs = Collections.singletonMap(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE,
-                    bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE));
-        }
-        else
-        {
-            dirs = Collections.emptyMap();
-        }
-        Capability cap = new CapabilityImpl(null, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs);
-        return cap;
-    }
-
-    private static List<Requirement> parseFragmentHost(
-            Manifest headerMap)
-            throws BundleException
-    {
-        List<Requirement> reqs = new ArrayList<>();
-
-        String mv = getManifestVersion(headerMap);
-        if ((mv != null) && mv.equals("2"))
-        {
-            List<ParsedHeaderClause> clauses = parseStandardHeader(
-                    headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
-            if (clauses.size() > 0)
-            {
-                // Make sure that only one fragment host symbolic name is specified.
-                if (clauses.size() > 1)
-                {
-                    throw new BundleException(
-                            "Fragments cannot have multiple hosts: "
-                                    + headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
-                }
-                else if (clauses.get(0).m_paths.size() > 1)
-                {
-                    throw new BundleException(
-                            "Fragments cannot have multiple hosts: "
-                                    + headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST));
-                }
-
-                // If the bundle-version attribute is specified, then convert
-                // it to the proper type.
-                Object value = clauses.get(0).m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
-                value = (value == null) ? "0.0.0" : value;
-                if (value != null)
-                {
-                    clauses.get(0).m_attrs.put(
-                            Constants.BUNDLE_VERSION_ATTRIBUTE,
-                            VersionRange.valueOf(value.toString()));
-                }
-
-                // Note that we use a linked hash map here to ensure the
-                // host symbolic name is first, which will make indexing
-                // more efficient.
-// TODO: OSGi R4.3 - This is ordering is kind of hacky.
-                // Prepend the host symbolic name to the map of attributes.
-                Map<String, Object> attrs = clauses.get(0).m_attrs;
-                Map<String, Object> newAttrs = new LinkedHashMap<>(attrs.size() + 1);
-                // We want this first from an indexing perspective.
-                newAttrs.put(
-                        BundleRevision.HOST_NAMESPACE,
-                        clauses.get(0).m_paths.get(0));
-                newAttrs.putAll(attrs);
-                // But we need to put it again to make sure it wasn't overwritten.
-                newAttrs.put(
-                        BundleRevision.HOST_NAMESPACE,
-                        clauses.get(0).m_paths.get(0));
-
-                // Create filter now so we can inject filter directive.
-                SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
-                // Inject filter directive.
-// TODO: OSGi R4.3 - Can we insert this on demand somehow?
-                Map<String, String> dirs = clauses.get(0).m_dirs;
-                Map<String, String> newDirs = new HashMap<>(dirs.size() + 1);
-                newDirs.putAll(dirs);
-                newDirs.put(
-                        Constants.FILTER_DIRECTIVE,
-                        sf.toString());
-
-                Requirement req = new RequirementImpl(null, BundleRevision.HOST_NAMESPACE, newDirs, newAttrs);
-                reqs.add(req);
-            }
-        }
-        else if (headerMap.getMainAttributes().getValue(Constants.FRAGMENT_HOST) != null)
-        {
-            String s = headerMap.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
-            s = (s == null) ? headerMap.getMainAttributes().getValue(Constants.BUNDLE_NAME) : s;
-            s = (s == null) ? headerMap.toString() : s;
-        }
-
-        return reqs;
-    }
-
-
-    private static List<Requirement> parseBreeHeader(String header)
-    {
-        List<String> filters = new ArrayList<>();
-        for (String entry : parseDelimitedString(header, ","))
-        {
-            List<String> names = parseDelimitedString(entry, "/");
-            List<String> left = parseDelimitedString(names.get(0), "-");
-
-            String lName = left.get(0);
-            Version lVer;
-            try
-            {
-                lVer = Version.parseVersion(left.get(1));
-            }
-            catch (Exception ex)
-            {
-                // Version doesn't parse. Make it part of the name.
-                lName = names.get(0);
-                lVer = null;
-            }
-
-            String rName = null;
-            Version rVer = null;
-            if (names.size() > 1)
-            {
-                List<String> right = parseDelimitedString(names.get(1), "-");
-                rName = right.get(0);
-                try
-                {
-                    rVer = Version.parseVersion(right.get(1));
-                }
-                catch (Exception ex)
-                {
-                    rName = names.get(1);
-                    rVer = null;
-                }
-            }
-
-            String versionClause;
-            if (lVer != null)
-            {
-                if ((rVer != null) && (!rVer.equals(lVer)))
-                {
-                    // Both versions are defined, but different. Make each of them part of the name
-                    lName = names.get(0);
-                    rName = names.get(1);
-                    versionClause = null;
-                }
-                else
-                {
-                    versionClause = getBreeVersionClause(lVer);
-                }
-            }
-            else
-            {
-                versionClause = getBreeVersionClause(rVer);
-            }
-
-            if ("J2SE".equals(lName))
-            {
-                // J2SE is not used in the Capability variant of BREE, use JavaSE here
-                // This can only happen with the lName part...
-                lName = "JavaSE";
-            }
-
-            String nameClause;
-            if (rName != null)
-                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + "/" + rName + ")";
-            else
-                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + ")";
-
-            String filter;
-            if (versionClause != null)
-                filter = "(&" + nameClause + versionClause + ")";
-            else
-                filter = nameClause;
-
-            filters.add(filter);
-        }
-
-        if (filters.size() == 0)
-        {
-            return Collections.emptyList();
-        }
-        else
-        {
-            String reqFilter;
-            if (filters.size() == 1)
-            {
-                reqFilter = filters.get(0);
-            }
-            else
-            {
-                // If there are more BREE filters, we need to or them together
-                StringBuilder sb = new StringBuilder("(|");
-                for (String f : filters)
-                {
-                    sb.append(f);
-                }
-                sb.append(")");
-                reqFilter = sb.toString();
-            }
-
-            SimpleFilter sf = SimpleFilter.parse(reqFilter);
-            Requirement req = new RequirementImpl(null, ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE,
-                    Collections.singletonMap(ExecutionEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, reqFilter), null);
-            return Collections.<Requirement>singletonList(req);
-        }
-    }
-
-    private static String getBreeVersionClause(Version ver) {
-        if (ver == null)
-            return null;
-
-        return "(" + ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE + "=" + ver + ")";
-    }
-
-    static List<ParsedHeaderClause> normalizeRequireClauses(List<ParsedHeaderClause> clauses, String mv)
-    {
-        // R3 bundles cannot require other bundles.
-        if (!mv.equals("2"))
-        {
-            clauses.clear();
-        }
-        else
-        {
-            // Convert bundle version attribute to VersionRange type.
-            for (ParsedHeaderClause clause : clauses)
-            {
-                Object value = clause.m_attrs.get(Constants.BUNDLE_VERSION_ATTRIBUTE);
-                if (value != null)
-                {
-                    clause.m_attrs.put(
-                            Constants.BUNDLE_VERSION_ATTRIBUTE,
-                            VersionRange.valueOf(value.toString()));
-                }
-            }
-        }
-
-        return clauses;
-    }
-
-    private static List<Requirement> convertRequires(
-            List<ParsedHeaderClause> clauses)
-    {
-        List<Requirement> reqList = new ArrayList<>();
-        for (ParsedHeaderClause clause : clauses)
-        {
-            for (String path : clause.m_paths)
-            {
-                // Prepend the bundle symbolic name to the array of attributes.
-                Map<String, Object> attrs = clause.m_attrs;
-                // Note that we use a linked hash map here to ensure the
-                // symbolic name attribute is first, which will make indexing
-                // more efficient.
-// TODO: OSGi R4.3 - This is ordering is kind of hacky.
-                // Prepend the symbolic name to the array of attributes.
-                Map<String, Object> newAttrs = new LinkedHashMap<>(attrs.size() + 1);
-                // We want this first from an indexing perspective.
-                newAttrs.put(
-                        BundleRevision.BUNDLE_NAMESPACE,
-                        path);
-                newAttrs.putAll(attrs);
-                // But we need to put it again to make sure it wasn't overwritten.
-                newAttrs.put(
-                        BundleRevision.BUNDLE_NAMESPACE,
-                        path);
-
-                // Create filter now so we can inject filter directive.
-                SimpleFilter sf = SimpleFilter.convert(newAttrs);
-
-                // Inject filter directive.
-// TODO: OSGi R4.3 - Can we insert this on demand somehow?
-                Map<String, String> dirs = clause.m_dirs;
-                Map<String, String> newDirs = new HashMap<>(dirs.size() + 1);
-                newDirs.putAll(dirs);
-                newDirs.put(
-                        Constants.FILTER_DIRECTIVE,
-                        sf.toString());
-
-                Requirement req = new RequirementImpl(null, BundleRevision.BUNDLE_NAMESPACE, newDirs, newAttrs);
-                reqList.add(req);
-            }
-        }
-
-        return reqList;
-    }
-
-    private static final char EOF = (char) -1;
-
-    private static char charAt(int pos, String headers, int length)
-    {
-        if (pos >= length)
-        {
-            return EOF;
-        }
-        return headers.charAt(pos);
-    }
-
-    private static final int CLAUSE_START = 0;
-    private static final int PARAMETER_START = 1;
-    private static final int KEY = 2;
-    private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
-    private static final int ARGUMENT = 8;
-    private static final int VALUE = 16;
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static List<ParsedHeaderClause> parseStandardHeader(String header)
-    {
-        List<ParsedHeaderClause> clauses = new ArrayList<>();
-        if (header == null)
-        {
-            return clauses;
-        }
-        ParsedHeaderClause clause = null;
-        String key = null;
-        Map targetMap = null;
-        int state = CLAUSE_START;
-        int currentPosition = 0;
-        int startPosition = 0;
-        int length = header.length();
-        boolean quoted = false;
-        boolean escaped = false;
-
-        char currentChar = EOF;
-        do
-        {
-            currentChar = charAt(currentPosition, header, length);
-            switch (state)
-            {
-                case CLAUSE_START:
-                    clause = new ParsedHeaderClause(
-                            new ArrayList<>(),
-                            new HashMap<>(),
-                            new HashMap<>(),
-                            new HashMap<>());
-                    clauses.add(clause);
-                    state = PARAMETER_START;
-                case PARAMETER_START:
-                    startPosition = currentPosition;
-                    state = KEY;
-                case KEY:
-                    switch (currentChar)
-                    {
-                        case ':':
-                        case '=':
-                            key = header.substring(startPosition, currentPosition).trim();
-                            startPosition = currentPosition + 1;
-                            targetMap = clause.m_attrs;
-                            state = currentChar == ':' ? DIRECTIVE_OR_TYPEDATTRIBUTE : ARGUMENT;
-                            break;
-                        case EOF:
-                        case ',':
-                        case ';':
-                            clause.m_paths.add(header.substring(startPosition, currentPosition).trim());
-                            state = currentChar == ',' ? CLAUSE_START : PARAMETER_START;
-                            break;
-                        default:
-                            break;
-                    }
-                    currentPosition++;
-                    break;
-                case DIRECTIVE_OR_TYPEDATTRIBUTE:
-                    switch(currentChar)
-                    {
-                        case '=':
-                            if (startPosition != currentPosition)
-                            {
-                                clause.m_types.put(key, header.substring(startPosition, currentPosition).trim());
-                            }
-                            else
-                            {
-                                targetMap = clause.m_dirs;
-                            }
-                            state = ARGUMENT;
-                            startPosition = currentPosition + 1;
-                            break;
-                        default:
-                            break;
-                    }
-                    currentPosition++;
-                    break;
-                case ARGUMENT:
-                    if (currentChar == '\"')
-                    {
-                        quoted = true;
-                        currentPosition++;
-                    }
-                    else
-                    {
-                        quoted = false;
-                    }
-                    if (!Character.isWhitespace(currentChar)) {
-                        state = VALUE;
-                    }
-                    else {
-                        currentPosition++;
-                    }
-                    break;
-                case VALUE:
-                    if (escaped)
-                    {
-                        escaped = false;
-                    }
-                    else
-                    {
-                        if (currentChar == '\\' )
-                        {
-                            escaped = true;
-                        }
-                        else if (quoted && currentChar == '\"')
-                        {
-                            quoted = false;
-                        }
-                        else if (!quoted)
-                        {
-                            String value = null;
-                            switch(currentChar)
-                            {
-                                case EOF:
-                                case ';':
-                                case ',':
-                                    value = header.substring(startPosition, currentPosition).trim();
-                                    if (value.startsWith("\"") && value.endsWith("\""))
-                                    {
-                                        value = value.substring(1, value.length() - 1);
-                                    }
-                                    if (targetMap.put(key, value) != null)
-                                    {
-                                        throw new IllegalArgumentException(
-                                                "Duplicate '" + key + "' in: " + header);
-                                    }
-                                    state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
-                                    break;
-                                default:
-                                    break;
-                            }
-                        }
-                    }
-                    currentPosition++;
-                    break;
-                default:
-                    break;
-            }
-        } while ( currentChar != EOF);
-
-        if (state > PARAMETER_START)
-        {
-            throw new IllegalArgumentException("Unable to parse header: " + header);
-        }
-        return clauses;
-    }
-
-    public static List<String> parseDelimitedString(String value, String delim)
-    {
-        return parseDelimitedString(value, delim, true);
-    }
-
-    /**
-     * Parses delimited string and returns an array containing the tokens. This
-     * parser obeys quotes, so the delimiter character will be ignored if it is
-     * inside of a quote. This method assumes that the quote character is not
-     * included in the set of delimiter characters.
-     * @param value the delimited string to parse.
-     * @param delim the characters delimiting the tokens.
-     * @return a list of string or an empty list if there are none.
-     **/
-    public static List<String> parseDelimitedString(String value, String delim, boolean trim)
-    {
-        if (value == null)
-        {
-            value = "";
-        }
-
-        List<String> list = new ArrayList<>();
-
-        int CHAR = 1;
-        int DELIMITER = 2;
-        int STARTQUOTE = 4;
-        int ENDQUOTE = 8;
-
-        StringBuffer sb = new StringBuffer();
-
-        int expecting = (CHAR | DELIMITER | STARTQUOTE);
-
-        boolean isEscaped = false;
-        for (int i = 0; i < value.length(); i++)
-        {
-            char c = value.charAt(i);
-
-            boolean isDelimiter = (delim.indexOf(c) >= 0);
-
-            if (!isEscaped && (c == '\\'))
-            {
-                isEscaped = true;
-                continue;
-            }
-
-            if (isEscaped)
-            {
-                sb.append(c);
-            }
-            else if (isDelimiter && ((expecting & DELIMITER) > 0))
-            {
-                if (trim)
-                {
-                    list.add(sb.toString().trim());
-                }
-                else
-                {
-                    list.add(sb.toString());
-                }
-                sb.delete(0, sb.length());
-                expecting = (CHAR | DELIMITER | STARTQUOTE);
-            }
-            else if ((c == '"') && ((expecting & STARTQUOTE) > 0))
-            {
-                sb.append(c);
-                expecting = CHAR | ENDQUOTE;
-            }
-            else if ((c == '"') && ((expecting & ENDQUOTE) > 0))
-            {
-                sb.append(c);
-                expecting = (CHAR | STARTQUOTE | DELIMITER);
-            }
-            else if ((expecting & CHAR) > 0)
-            {
-                sb.append(c);
-            }
-            else
-            {
-                throw new IllegalArgumentException("Invalid delimited string: " + value);
-            }
-
-            isEscaped = false;
-        }
-
-        if (sb.length() > 0)
-        {
-            if (trim)
-            {
-                list.add(sb.toString().trim());
-            }
-            else
-            {
-                list.add(sb.toString());
-            }
-        }
-
-        return list;
-    }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java
deleted file mode 100644
index 2b3772d..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/ManifestUtil.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.support.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.stream.Collectors;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-public class ManifestUtil {
-
-    /**
-     * Get the manifest from the artifact.
-     * @param artifact The file
-     * @throws IOException If the manifest can't be read
-     */
-    public static Manifest getManifest(final File artifact) throws IOException {
-        try (final JarFile file = new JarFile(artifact) ) {
-            return file.getManifest();
-        }
-    }
-
-    public static List<PackageInfo> extractPackages(final Manifest m,
-            final String headerName,
-            final String defaultVersion,
-            final boolean checkOptional) {
-        final String pckInfo = m.getMainAttributes().getValue(headerName);
-        if (pckInfo != null) {
-            final List<ManifestParser.ParsedHeaderClause> clauses = ManifestParser.parseStandardHeader(pckInfo);
-
-            final List<PackageInfo> pcks = new ArrayList<>();
-            for(final ManifestParser.ParsedHeaderClause entry : clauses) {
-                Object versionObj = entry.m_attrs.get("version");
-                final String version;
-                if ( versionObj == null ) {
-                    version = defaultVersion;
-                } else {
-                    version = versionObj.toString();
-                }
-
-                boolean optional = false;
-                if ( checkOptional ) {
-                    final String resolution = entry.m_dirs.get("resolution");
-                    optional = "optional".equalsIgnoreCase(resolution);
-                }
-                for(final String path : entry.m_paths) {
-                    final PackageInfo pck = new PackageInfo(path,
-                        version,
-                        optional);
-                    pcks.add(pck);
-                }
-            }
-
-            return pcks;
-        }
-        return Collections.emptyList();
-    }
-
-    public static List<PackageInfo> extractExportedPackages(final Manifest m) {
-        return extractPackages(m, Constants.EXPORT_PACKAGE, "0.0.0", false);
-    }
-
-    public static List<PackageInfo> extractImportedPackages(final Manifest m) {
-        return extractPackages(m, Constants.IMPORT_PACKAGE, null, true);
-    }
-
-    public static List<PackageInfo> extractDynamicImportedPackages(final Manifest m) {
-        return extractPackages(m, Constants.DYNAMICIMPORT_PACKAGE, null, false);
-    }
-
-    public static List<Capability> extractCapabilities(ManifestParser parser) {
-        return parser.getCapabilities();
-    }
-
-    public static List<Requirement> extractRequirements(ManifestParser parser)  {
-        return parser.getRequirements();
-    }
-
-    public static void unmarshalAttribute(String key, Object value, BiConsumer<String, Object> sink) throws IOException {
-        unmarshal(key + "=" + value, Capability::getAttributes, sink);
-    }
-
-    public static void unmarshalDirective(String key, Object value, BiConsumer<String, String> sink) throws IOException {
-        unmarshal(key + ":=" + value, Capability::getDirectives, sink);
-    }
-
-    private static <T> void unmarshal(String header, Function<Capability, Map<String, T>> lookup, BiConsumer<String, T> sink) throws IOException {
-        try {
-            ManifestParser.convertProvideCapabilities(
-                    ManifestParser.normalizeCapabilityClauses(ManifestParser.parseStandardHeader("foo;" + header), "2"))
-                    .forEach(capability -> lookup.apply(capability).forEach(sink));
-        } catch (Exception e) {
-            throw new IOException(e);
-        }
-    }
-
-    public static void marshalAttribute(String key, Object value, BiConsumer<String, String> sink) {
-        marshal(key, value, sink);
-    }
-
-    public static void marshalDirective(String key, Object value, BiConsumer<String, String> sink) {
-        marshal(key, value, sink);
-    }
-
-    private static void marshal(String key, Object value, BiConsumer<String, String> sink) {
-        StringBuilder keyBuilder = new StringBuilder(key);
-        if (value instanceof  List) {
-            List list = (List) value;
-            keyBuilder.append(":List");
-            if (!list.isEmpty()) {
-                String type = type(list.get(0));
-                if (!type.equals("String")) {
-                    keyBuilder.append('<').append(type).append('>');
-                }
-                value = list.stream().map(
-                        v -> v.toString().replace(",", "\\,")
-                ).collect(Collectors.joining(","));
-            }
-            else {
-                value = "";
-            }
-        }
-        else {
-            String type = type(value);
-            if (!type.equals("String")) {
-                keyBuilder.append(':').append(type);
-            }
-        }
-        sink.accept(keyBuilder.toString(), value.toString());
-    }
-
-    private static String type(Object value) {
-        if (value instanceof Long) {
-            return "Long";
-        }
-        else if (value instanceof Double)
-        {
-            return "Double";
-        }
-        else if (value instanceof Version)
-        {
-            return "Version";
-        }
-        else
-        {
-            return "String";
-        }
-    }
-}
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java
deleted file mode 100644
index f9dc1cc..0000000
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/util/SimpleFilter.java
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.support.util;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.osgi.framework.VersionRange;
-
-class SimpleFilter
-{
-    public static final int MATCH_ALL = 0;
-    public static final int AND = 1;
-    public static final int OR = 2;
-    public static final int NOT = 3;
-    public static final int EQ = 4;
-    public static final int LTE = 5;
-    public static final int GTE = 6;
-    public static final int SUBSTRING = 7;
-    public static final int PRESENT = 8;
-    public static final int APPROX = 9;
-
-    private final String m_name;
-    private final Object m_value;
-    private final int m_op;
-
-    SimpleFilter(String attr, Object value, int op)
-    {
-        m_name = attr;
-        m_value = value;
-        m_op = op;
-    }
-
-    public String getName()
-    {
-        return m_name;
-    }
-
-    public Object getValue()
-    {
-        return m_value;
-    }
-
-    public int getOperation()
-    {
-        return m_op;
-    }
-
-    @Override
-    public String toString()
-    {
-        String s = null;
-        switch (m_op)
-        {
-            case AND:
-                s = "(&" + toString((List) m_value) + ")";
-                break;
-            case OR:
-                s = "(|" + toString((List) m_value) + ")";
-                break;
-            case NOT:
-                s = "(!" + toString((List) m_value) + ")";
-                break;
-            case EQ:
-                s = "(" + m_name + "=" + toEncodedString(m_value) + ")";
-                break;
-            case LTE:
-                s = "(" + m_name + "<=" + toEncodedString(m_value) + ")";
-                break;
-            case GTE:
-                s = "(" + m_name + ">=" + toEncodedString(m_value) + ")";
-                break;
-            case SUBSTRING:
-                s = "(" + m_name + "=" + unparseSubstring((List<String>) m_value) + ")";
-                break;
-            case PRESENT:
-                s = "(" + m_name + "=*)";
-                break;
-            case APPROX:
-                s = "(" + m_name + "~=" + toEncodedString(m_value) + ")";
-                break;
-            case MATCH_ALL:
-                s = "(*)";
-                break;
-        }
-        return s;
-    }
-
-    private static String toString(List list)
-    {
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < list.size(); i++)
-        {
-            sb.append(list.get(i).toString());
-        }
-        return sb.toString();
-    }
-
-    private static String toDecodedString(String s, int startIdx, int endIdx)
-    {
-        StringBuffer sb = new StringBuffer(endIdx - startIdx);
-        boolean escaped = false;
-        for (int i = 0; i < (endIdx - startIdx); i++)
-        {
-            char c = s.charAt(startIdx + i);
-            if (!escaped && (c == '\\'))
-            {
-                escaped = true;
-            }
-            else
-            {
-                escaped = false;
-                sb.append(c);
-            }
-        }
-
-        return sb.toString();
-    }
-
-    private static String toEncodedString(Object o)
-    {
-        if (o instanceof String)
-        {
-            String s = (String) o;
-            StringBuffer sb = new StringBuffer();
-            for (int i = 0; i < s.length(); i++)
-            {
-                char c = s.charAt(i);
-                if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
-                {
-                    sb.append('\\');
-                }
-                sb.append(c);
-            }
-
-            o = sb.toString();
-        }
-
-        return o.toString();
-    }
-
-    public static SimpleFilter parse(String filter)
-    {
-        int idx = skipWhitespace(filter, 0);
-
-        if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
-        {
-            throw new IllegalArgumentException("Null or empty filter.");
-        }
-        else if (filter.charAt(idx) != '(')
-        {
-            throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
-        }
-
-        SimpleFilter sf = null;
-        List stack = new ArrayList();
-        boolean isEscaped = false;
-        while (idx < filter.length())
-        {
-            if (sf != null)
-            {
-                throw new IllegalArgumentException(
-                        "Only one top-level operation allowed: " + filter);
-            }
-
-            if (!isEscaped && (filter.charAt(idx) == '('))
-            {
-                // Skip paren and following whitespace.
-                idx = skipWhitespace(filter, idx + 1);
-
-                if (filter.charAt(idx) == '&')
-                {
-                    int peek = skipWhitespace(filter, idx + 1);
-                    if (filter.charAt(peek) == '(')
-                    {
-                        idx = peek - 1;
-                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
-                    }
-                    else
-                    {
-                        stack.add(0, new Integer(idx));
-                    }
-                }
-                else if (filter.charAt(idx) == '|')
-                {
-                    int peek = skipWhitespace(filter, idx + 1);
-                    if (filter.charAt(peek) == '(')
-                    {
-                        idx = peek - 1;
-                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
-                    }
-                    else
-                    {
-                        stack.add(0, new Integer(idx));
-                    }
-                }
-                else if (filter.charAt(idx) == '!')
-                {
-                    int peek = skipWhitespace(filter, idx + 1);
-                    if (filter.charAt(peek) == '(')
-                    {
-                        idx = peek - 1;
-                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
-                    }
-                    else
-                    {
-                        stack.add(0, new Integer(idx));
-                    }
-                }
-                else
-                {
-                    stack.add(0, new Integer(idx));
-                }
-            }
-            else if (!isEscaped && (filter.charAt(idx) == ')'))
-            {
-                Object top = stack.remove(0);
-                if (top instanceof SimpleFilter)
-                {
-                    if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
-                    {
-                        ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
-                    }
-                    else
-                    {
-                        sf = (SimpleFilter) top;
-                    }
-                }
-                else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
-                {
-                    ((List) ((SimpleFilter) stack.get(0)).m_value).add(
-                            SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx));
-                }
-                else
-                {
-                    sf = SimpleFilter.subfilter(filter, ((Integer) top).intValue(), idx);
-                }
-            }
-            else if (!isEscaped && (filter.charAt(idx) == '\\'))
-            {
-                isEscaped = true;
-            }
-            else
-            {
-                isEscaped = false;
-            }
-
-            idx = skipWhitespace(filter, idx + 1);
-        }
-
-        if (sf == null)
-        {
-            throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
-        }
-
-        return sf;
-    }
-
-    private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
-    {
-        final String opChars = "=<>~";
-
-        // Determine the ending index of the attribute name.
-        int attrEndIdx = startIdx;
-        for (int i = 0; i < (endIdx - startIdx); i++)
-        {
-            char c = filter.charAt(startIdx + i);
-            if (opChars.indexOf(c) >= 0)
-            {
-                break;
-            }
-            else if (!Character.isWhitespace(c))
-            {
-                attrEndIdx = startIdx + i + 1;
-            }
-        }
-        if (attrEndIdx == startIdx)
-        {
-            throw new IllegalArgumentException(
-                    "Missing attribute name: " + filter.substring(startIdx, endIdx));
-        }
-        String attr = filter.substring(startIdx, attrEndIdx);
-
-        // Skip the attribute name and any following whitespace.
-        startIdx = skipWhitespace(filter, attrEndIdx);
-
-        // Determine the operator type.
-        int op = -1;
-        switch (filter.charAt(startIdx))
-        {
-            case '=':
-                op = EQ;
-                startIdx++;
-                break;
-            case '<':
-                if (filter.charAt(startIdx + 1) != '=')
-                {
-                    throw new IllegalArgumentException(
-                            "Unknown operator: " + filter.substring(startIdx, endIdx));
-                }
-                op = LTE;
-                startIdx += 2;
-                break;
-            case '>':
-                if (filter.charAt(startIdx + 1) != '=')
-                {
-                    throw new IllegalArgumentException(
-                            "Unknown operator: " + filter.substring(startIdx, endIdx));
-                }
-                op = GTE;
-                startIdx += 2;
-                break;
-            case '~':
-                if (filter.charAt(startIdx + 1) != '=')
-                {
-                    throw new IllegalArgumentException(
-                            "Unknown operator: " + filter.substring(startIdx, endIdx));
-                }
-                op = APPROX;
-                startIdx += 2;
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "Unknown operator: " + filter.substring(startIdx, endIdx));
-        }
-
-        // Parse value.
-        Object value = toDecodedString(filter, startIdx, endIdx);
-
-        // Check if the equality comparison is actually a substring
-        // or present operation.
-        if (op == EQ)
-        {
-            String valueStr = filter.substring(startIdx, endIdx);
-            List<String> values = parseSubstring(valueStr);
-            if ((values.size() == 2)
-                    && (values.get(0).length() == 0)
-                    && (values.get(1).length() == 0))
-            {
-                op = PRESENT;
-            }
-            else if (values.size() > 1)
-            {
-                op = SUBSTRING;
-                value = values;
-            }
-        }
-
-        return new SimpleFilter(attr, value, op);
-    }
-
-    public static List<String> parseSubstring(String value)
-    {
-        List<String> pieces = new ArrayList();
-        StringBuffer ss = new StringBuffer();
-        // int kind = SIMPLE; // assume until proven otherwise
-        boolean wasStar = false; // indicates last piece was a star
-        boolean leftstar = false; // track if the initial piece is a star
-        boolean rightstar = false; // track if the final piece is a star
-
-        int idx = 0;
-
-        // We assume (sub)strings can contain leading and trailing blanks
-        boolean escaped = false;
-        loop:   for (;;)
-        {
-            if (idx >= value.length())
-            {
-                if (wasStar)
-                {
-                    // insert last piece as "" to handle trailing star
-                    rightstar = true;
-                }
-                else
-                {
-                    pieces.add(ss.toString());
-                    // accumulate the last piece
-                    // note that in the case of
-                    // (cn=); this might be
-                    // the string "" (!=null)
-                }
-                ss.setLength(0);
-                break loop;
-            }
-
-            // Read the next character and account for escapes.
-            char c = value.charAt(idx++);
-            if (!escaped && (c == '*'))
-            {
-                // If we have successive '*' characters, then we can
-                // effectively collapse them by ignoring succeeding ones.
-                if (!wasStar)
-                {
-                    if (ss.length() > 0)
-                    {
-                        pieces.add(ss.toString()); // accumulate the pieces
-                        // between '*' occurrences
-                    }
-                    ss.setLength(0);
-                    // if this is a leading star, then track it
-                    if (pieces.isEmpty())
-                    {
-                        leftstar = true;
-                    }
-                    wasStar = true;
-                }
-            }
-            else if (!escaped && (c == '\\'))
-            {
-                escaped = true;
-            }
-            else
-            {
-                escaped = false;
-                wasStar = false;
-                ss.append(c);
-            }
-        }
-        if (leftstar || rightstar || pieces.size() > 1)
-        {
-            // insert leading and/or trailing "" to anchor ends
-            if (rightstar)
-            {
-                pieces.add("");
-            }
-            if (leftstar)
-            {
-                pieces.add(0, "");
-            }
-        }
-        return pieces;
-    }
-
-    public static String unparseSubstring(List<String> pieces)
-    {
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < pieces.size(); i++)
-        {
-            if (i > 0)
-            {
-                sb.append("*");
-            }
-            sb.append(toEncodedString(pieces.get(i)));
-        }
-        return sb.toString();
-    }
-
-    public static boolean compareSubstring(List<String> pieces, String s)
-    {
-        // Walk the pieces to match the string
-        // There are implicit stars between each piece,
-        // and the first and last pieces might be "" to anchor the match.
-        // assert (pieces.length > 1)
-        // minimal case is <string>*<string>
-
-        boolean result = true;
-        int len = pieces.size();
-
-        // Special case, if there is only one piece, then
-        // we must perform an equality test.
-        if (len == 1)
-        {
-            return s.equals(pieces.get(0));
-        }
-
-        // Otherwise, check whether the pieces match
-        // the specified string.
-
-        int index = 0;
-
-        loop:   for (int i = 0; i < len; i++)
-        {
-            String piece = pieces.get(i);
-
-            // If this is the first piece, then make sure the
-            // string starts with it.
-            if (i == 0)
-            {
-                if (!s.startsWith(piece))
-                {
-                    result = false;
-                    break loop;
-                }
-            }
-
-            // If this is the last piece, then make sure the
-            // string ends with it.
-            if (i == (len - 1))
-            {
-                if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
-                {
-                    result = true;
-                }
-                else
-                {
-                    result = false;
-                }
-                break loop;
-            }
-
-            // If this is neither the first or last piece, then
-            // make sure the string contains it.
-            if ((i > 0) && (i < (len - 1)))
-            {
-                index = s.indexOf(piece, index);
-                if (index < 0)
-                {
-                    result = false;
-                    break loop;
-                }
-            }
-
-            // Move string index beyond the matching piece.
-            index += piece.length();
-        }
-
-        return result;
-    }
-
-    private static int skipWhitespace(String s, int startIdx)
-    {
-        int len = s.length();
-        while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
-        {
-            startIdx++;
-        }
-        return startIdx;
-    }
-
-    /**
-     * Converts a attribute map to a filter. The filter is created by iterating
-     * over the map's entry set. If ordering of attributes is important (e.g.,
-     * for hitting attribute indices), then the map's entry set should iterate
-     * in the desired order. Equality testing is assumed for all attribute types
-     * other than version ranges, which are handled appropriated. If the attribute
-     * map is empty, then a filter that matches anything is returned.
-     * @param attrs Map of attributes to convert to a filter.
-     * @return A filter corresponding to the attributes.
-     */
-    public static SimpleFilter convert(Map<String, Object> attrs)
-    {
-        // Rather than building a filter string to be parsed into a SimpleFilter,
-        // we will just create the parsed SimpleFilter directly.
-
-        List<SimpleFilter> filters = new ArrayList<>();
-
-        for (Entry<String, Object> entry : attrs.entrySet())
-        {
-            if (entry.getValue() instanceof VersionRange)
-            {
-                VersionRange vr = (VersionRange) entry.getValue();
-                if (vr.getLeftType() == VersionRange.LEFT_CLOSED)
-                {
-                    filters.add(
-                            new SimpleFilter(
-                                    entry.getKey(),
-                                    vr.getLeft().toString(),
-                                    SimpleFilter.GTE));
-                }
-                else
-                {
-                    SimpleFilter not =
-                            new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
-                    ((List) not.getValue()).add(
-                            new SimpleFilter(
-                                    entry.getKey(),
-                                    vr.getLeft().toString(),
-                                    SimpleFilter.LTE));
-                    filters.add(not);
-                }
-
-                if (vr.getRight() != null)
-                {
-                    if (vr.getRightType() == VersionRange.RIGHT_CLOSED)
-                    {
-                        filters.add(
-                                new SimpleFilter(
-                                        entry.getKey(),
-                                        vr.getRight().toString(),
-                                        SimpleFilter.LTE));
-                    }
-                    else
-                    {
-                        SimpleFilter not =
-                                new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT);
-                        ((List) not.getValue()).add(
-                                new SimpleFilter(
-                                        entry.getKey(),
-                                        vr.getRight().toString(),
-                                        SimpleFilter.GTE));
-                        filters.add(not);
-                    }
-                }
-            }
-            else
-            {
-                List<String> values = SimpleFilter.parseSubstring(entry.getValue().toString());
-                if (values.size() > 1)
-                {
-                    filters.add(
-                            new SimpleFilter(
-                                    entry.getKey(),
-                                    values,
-                                    SimpleFilter.SUBSTRING));
-                }
-                else
-                {
-                    filters.add(
-                            new SimpleFilter(
-                                    entry.getKey(),
-                                    values.get(0),
-                                    SimpleFilter.EQ));
-                }
-            }
-        }
-
-        SimpleFilter sf = null;
-
-        if (filters.size() == 1)
-        {
-            sf = filters.get(0);
-        }
-        else if (attrs.size() > 1)
-        {
-            sf = new SimpleFilter(null, filters, SimpleFilter.AND);
-        }
-        else if (filters.isEmpty())
-        {
-            sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
-        }
-
-        return sf;
-    }
-}
diff --git a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java b/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java
deleted file mode 100644
index ea62869..0000000
--- a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/util/ManifestUtilTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.support.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-import java.util.jar.Manifest;
-
-import org.junit.Test;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-public class ManifestUtilTest {
-
-    private void assertPackageInfo(final String name, final Version version, final PackageInfo info) {
-        assertEquals(name, info.getName());
-        assertEquals(version, info.getPackageVersion());
-    }
-
-    @Test public void testExportPackage() throws Exception {
-        final Manifest mf = new Manifest();
-        mf.getMainAttributes().putValue(Constants.EXPORT_PACKAGE, "org.apache.sling;version=1.0,org.apache.felix;version=2.0");
-        final List<PackageInfo> infos = ManifestUtil.extractExportedPackages(mf);
-        assertEquals(2, infos.size());
-        assertPackageInfo("org.apache.sling", Version.parseVersion("1.0"), infos.get(0));
-        assertPackageInfo("org.apache.felix", Version.parseVersion("2.0"), infos.get(1));
-    }
-}
diff --git a/featuremodel/osgifeature-maven-plugin/pom.xml b/featuremodel/osgifeature-maven-plugin/pom.xml
index ec05534..0d099b6 100644
--- a/featuremodel/osgifeature-maven-plugin/pom.xml
+++ b/featuremodel/osgifeature-maven-plugin/pom.xml
@@ -119,11 +119,6 @@
             <version>0.0.1-SNAPSHOT</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.support</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
             <groupId>org.apache.maven</groupId>
             <artifactId>maven-core</artifactId>
             <version>${maven.version}</version>
diff --git a/featuremodel/pom.xml b/featuremodel/pom.xml
index 1864df6..3293b7d 100644
--- a/featuremodel/pom.xml
+++ b/featuremodel/pom.xml
@@ -64,7 +64,6 @@
         <module>feature-launcher</module>
         <module>feature-modelconverter</module>
         <module>feature-resolver</module>
-        <module>feature-support</module>	
         <module>osgifeature-maven-plugin</module>
     </modules>
 

-- 
To stop receiving notification emails like this one, please contact
pauls@apache.org.