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

[sling-whiteboard] branch master updated: Remove feature modules that have been migrated to their own git repo

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

davidb 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 3269608  Remove feature modules that have been migrated to their own git repo
3269608 is described below

commit 32696080651ec9062853b28f222a0c0d72b70b5f
Author: David Bosschaert <bo...@adobe.com>
AuthorDate: Fri Apr 27 11:05:11 2018 +0100

    Remove feature modules that have been migrated to their own git repo
    
    The modules are:
    * feature now in sling-org-apache-sling-feature
    * feature-analyser now in sling-org-apache-sling-feature-analyser
    * feature-applicationbuilder now in sling-org-apache-sling-feature-applicationbuilder
    * feature-io now in sling-org-apache-sling-feature-io
    * feature-karaf now in sling-org-apache-sling-feature-karaf
    * feature-launcher now in sling-org-apache-sling-feature-launcher
    * feature-modelconverter now in sling-org-apache-sling-feature-modelconverter
    * feature-resolver now in sling-org-apache-sling-feature-resolver
    * osgifeature-maven-plugin now in sling-slingfeature-maven-plugin
---
 featuremodel/feature-analyser/pom.xml              | 159 ------
 .../apache/sling/feature/analyser/Analyser.java    | 125 -----
 .../apache/sling/feature/analyser/main/Main.java   |  74 ---
 .../sling/feature/analyser/package-info.java       |  23 -
 .../sling/feature/analyser/task/AnalyserTask.java  |  41 --
 .../feature/analyser/task/AnalyserTaskContext.java |  51 --
 .../task/impl/CheckBundleExportsImports.java       | 218 --------
 .../task/impl/CheckBundlesForInitialContent.java   |  85 ----
 .../task/impl/CheckBundlesForResources.java        |  82 ---
 .../task/impl/CheckRequirementsCapabilities.java   | 110 ----
 .../sling/feature/analyser/task/package-info.java  |  23 -
 .../feature/scanner/ApplicationDescriptor.java     |  39 --
 .../sling/feature/scanner/ArtifactDescriptor.java  |  39 --
 .../sling/feature/scanner/BundleDescriptor.java    |  94 ----
 .../sling/feature/scanner/ContainerDescriptor.java |  70 ---
 .../apache/sling/feature/scanner/Descriptor.java   |  92 ----
 .../sling/feature/scanner/FeatureDescriptor.java   |  28 -
 .../apache/sling/feature/scanner/PackageInfo.java  | 110 ----
 .../org/apache/sling/feature/scanner/Scanner.java  | 223 --------
 .../scanner/impl/ApplicationDescriptorImpl.java    |  52 --
 .../feature/scanner/impl/BundleDescriptorImpl.java | 194 -------
 .../scanner/impl/ContentPackageDescriptor.java     | 142 ------
 .../scanner/impl/ContentPackageScanner.java        | 357 -------------
 .../impl/ContentPackagesExtensionScanner.java      |  74 ---
 .../scanner/impl/FeatureDescriptorImpl.java        |  39 --
 .../scanner/impl/FelixFrameworkScanner.java        | 201 --------
 .../feature/scanner/impl/RepoInitScanner.java      |  65 ---
 .../apache/sling/feature/scanner/package-info.java |  23 -
 .../feature/scanner/spi/ExtensionScanner.java      |  48 --
 .../feature/scanner/spi/FrameworkScanner.java      |  44 --
 .../sling/feature/scanner/spi/package-info.java    |  23 -
 ...apache.sling.feature.analyser.task.AnalyserTask |   5 -
 ...ache.sling.feature.scanner.spi.ExtensionScanner |   3 -
 ...ache.sling.feature.scanner.spi.FrameworkScanner |   2 -
 .../scanner/impl/BundleDescriptorImplTest.java     |  73 ---
 .../scanner/impl/FelixFrameworkScannerTest.java    |  70 ---
 .../src/test/resources/test-framework.jar          | Bin 19945 -> 0 bytes
 featuremodel/feature-applicationbuilder/pom.xml    | 167 ------
 .../feature/applicationbuilder/impl/Main.java      | 203 --------
 .../impl/ApplicationBuilderTest.java               | 177 -------
 .../src/test/resources/featureA.json               |   5 -
 .../src/test/resources/featureB.json               |  14 -
 .../src/test/resources/featureC.json               |  18 -
 .../src/test/resources/featureD.json               |   5 -
 featuremodel/feature-io/pom.xml                    | 120 -----
 .../apache/sling/feature/io/ArtifactHandler.java   |  42 --
 .../apache/sling/feature/io/ArtifactManager.java   | 366 -------------
 .../sling/feature/io/ArtifactManagerConfig.java    | 142 ------
 .../java/org/apache/sling/feature/io/IOUtils.java  | 243 ---------
 .../feature/io/json/ApplicationJSONReader.java     |  92 ----
 .../feature/io/json/ApplicationJSONWriter.java     |  97 ----
 .../feature/io/json/ConfigurationJSONReader.java   |  78 ---
 .../feature/io/json/ConfigurationJSONWriter.java   |  64 ---
 .../sling/feature/io/json/FeatureJSONReader.java   | 431 ----------------
 .../sling/feature/io/json/FeatureJSONWriter.java   | 207 --------
 .../sling/feature/io/json/JSONConstants.java       |  88 ----
 .../sling/feature/io/json/JSONReaderBase.java      | 479 -----------------
 .../sling/feature/io/json/JSONWriterBase.java      | 259 ----------
 .../sling/feature/io/json/ManifestUtils.java       | 515 -------------------
 .../apache/sling/feature/io/json/package-info.java |  23 -
 .../org/apache/sling/feature/io/package-info.java  |  23 -
 .../sling/feature/io/spi/ArtifactProvider.java     |  55 --
 .../feature/io/spi/ArtifactProviderContext.java    |  46 --
 .../apache/sling/feature/io/spi/package-info.java  |  23 -
 .../sling/feature/io/ArtifactManagerTest.java      | 102 ----
 .../org/apache/sling/feature/io/IOUtilsTest.java   |  50 --
 .../feature/io/json/FeatureJSONReaderTest.java     | 222 --------
 .../feature/io/json/FeatureJSONWriterTest.java     |  50 --
 .../java/org/apache/sling/feature/io/json/U.java   |  89 ----
 .../src/test/resources/features/repoinit.json      |   4 -
 .../src/test/resources/features/repoinit2.json     |   7 -
 .../src/test/resources/features/test.json          |  92 ----
 .../src/test/resources/features/test2.json         | 107 ----
 .../src/test/resources/features/test3.json         | 116 -----
 featuremodel/feature-karaf/pom.xml                 |  78 ---
 .../sling/feature/karaf/ConfigurationUtil.java     |  87 ----
 .../sling/feature/karaf/KarafFeatureWriter.java    | 197 -------
 .../apache/sling/feature/karaf/package-info.java   |  23 -
 featuremodel/feature-launcher/pom.xml              | 140 -----
 .../feature/launcher/impl/FeatureProcessor.java    | 147 ------
 .../sling/feature/launcher/impl/Installation.java  | 137 -----
 .../feature/launcher/impl/LauncherConfig.java      | 122 -----
 .../apache/sling/feature/launcher/impl/Main.java   | 313 ------------
 .../launcher/impl/launchers/AbstractRunner.java    | 278 ----------
 .../launcher/impl/launchers/FrameworkLauncher.java | 102 ----
 .../launcher/impl/launchers/FrameworkRunner.java   |  70 ---
 .../sling/feature/launcher/spi/Launcher.java       |  26 -
 .../launcher/spi/LauncherPrepareContext.java       |  32 --
 .../feature/launcher/spi/LauncherRunContext.java   |  58 ---
 featuremodel/feature-modelconverter/pom.xml        | 176 -------
 .../modelconverter/impl/FeatureToProvisioning.java | 281 ----------
 .../sling/feature/modelconverter/impl/Main.java    | 208 --------
 .../modelconverter/impl/ProvisioningToFeature.java | 524 -------------------
 .../modelconverter/impl/ModelConverterTest.java    | 564 ---------------------
 .../src/test/resources/boot.json                   | 100 ----
 .../src/test/resources/boot.txt                    |  60 ---
 .../src/test/resources/boot_gav.json               | 100 ----
 .../src/test/resources/launchpad.json              |  28 -
 .../src/test/resources/launchpad.txt               |  20 -
 .../src/test/resources/oak.json                    |  97 ----
 .../src/test/resources/oak.txt                     |  91 ----
 .../src/test/resources/repoinit.json               |  74 ---
 .../src/test/resources/repoinit.txt                |  78 ---
 .../src/test/resources/simple.json                 |   9 -
 .../src/test/resources/simple.txt                  |  24 -
 featuremodel/feature-resolver/pom.xml              | 118 -----
 .../resolver/ApplicationResolverAssembler.java     | 128 -----
 .../sling/feature/resolver/FeatureResolver.java    |  38 --
 .../sling/feature/resolver/FeatureResource.java    |  52 --
 .../sling/feature/resolver/FrameworkResolver.java  | 310 -----------
 .../apache/sling/feature/resolver/Resolver.java    |  32 --
 .../sling/feature/resolver/ResolverContext.java    |  46 --
 .../resolver/impl/AbstractResourceImpl.java        |  50 --
 .../feature/resolver/impl/BundleResourceImpl.java  | 228 ---------
 .../feature/resolver/impl/FeatureResourceImpl.java | 174 -------
 .../feature/resolver/impl/ResolveContextImpl.java  |  96 ----
 .../sling/feature/resolver/AnalyserTest.java       | 115 -----
 .../feature/resolver/FrameworkResolverTest.java    | 149 ------
 .../feature/resolver/TestBundleResourceImpl.java   | 231 ---------
 .../resolver/impl/BundleResourceImplTest.java      | 208 --------
 .../resolver/impl/ResolveContextImplTest.java      | 126 -----
 .../src/test/resources/feature1.json               |   5 -
 .../src/test/resources/feature2.json               |   5 -
 .../src/test/resources/feature3.json               |  15 -
 .../src/test/resources/feature4.json               |   5 -
 .../src/test/resources/feature5.json               |  13 -
 .../src/test/resources/feature6.json               |  12 -
 .../src/test/resources/feature_complete.json       |  82 ---
 .../src/test/resources/feature_incomplete.json     |  82 ---
 featuremodel/feature/pom.xml                       | 101 ----
 .../java/org/apache/sling/feature/Application.java | 128 -----
 .../java/org/apache/sling/feature/Artifact.java    | 133 -----
 .../java/org/apache/sling/feature/ArtifactId.java  | 414 ---------------
 .../java/org/apache/sling/feature/Bundles.java     | 181 -------
 .../org/apache/sling/feature/Configuration.java    | 154 ------
 .../org/apache/sling/feature/Configurations.java   |  58 ---
 .../java/org/apache/sling/feature/Extension.java   | 184 -------
 .../org/apache/sling/feature/ExtensionType.java    |  27 -
 .../java/org/apache/sling/feature/Extensions.java  |  41 --
 .../java/org/apache/sling/feature/Feature.java     | 390 --------------
 .../org/apache/sling/feature/FeatureConstants.java |  25 -
 .../java/org/apache/sling/feature/Include.java     | 115 -----
 .../java/org/apache/sling/feature/KeyValueMap.java | 140 -----
 .../sling/feature/builder/ApplicationBuilder.java  | 153 ------
 .../sling/feature/builder/BuilderContext.java      |  81 ---
 .../apache/sling/feature/builder/BuilderUtil.java  | 267 ----------
 .../sling/feature/builder/FeatureBuilder.java      | 182 -------
 .../feature/builder/FeatureExtensionHandler.java   |  59 ---
 .../sling/feature/builder/FeatureProvider.java     |  36 --
 .../apache/sling/feature/builder/package-info.java |  23 -
 .../org/apache/sling/feature/package-info.java     |  23 -
 .../org/apache/sling/feature/ArtifactIdTest.java   | 149 ------
 .../java/org/apache/sling/feature/BundlesTest.java |  55 --
 .../sling/feature/builder/BuilderUtilTest.java     | 160 ------
 .../sling/feature/builder/FeatureBuilderTest.java  | 303 -----------
 featuremodel/osgifeature-maven-plugin/pom.xml      | 192 -------
 .../feature/maven/ApplicationProjectConfig.java    | 116 -----
 .../feature/maven/ApplicationProjectInfo.java      |  31 --
 .../apache/sling/feature/maven/Environment.java    |  35 --
 .../sling/feature/maven/FeatureConstants.java      |  32 --
 .../sling/feature/maven/FeatureProjectConfig.java  | 138 -----
 .../sling/feature/maven/FeatureProjectInfo.java    |  32 --
 .../apache/sling/feature/maven/Preprocessor.java   | 515 -------------------
 .../apache/sling/feature/maven/ProjectHelper.java  | 320 ------------
 .../apache/sling/feature/maven/ProjectInfo.java    |  27 -
 .../feature/maven/mojos/AbstractFeatureMojo.java   | 116 -----
 .../sling/feature/maven/mojos/AttachFeature.java   |  77 ---
 .../mojos/DependencyLifecycleParticipant.java      |  89 ----
 .../META-INF/m2e/lifecycle-mapping-metadata.xml    |  32 --
 .../main/resources/META-INF/plexus/components.xml  | 103 ----
 .../src/site/markdown/index.md                     |   6 -
 .../osgifeature-maven-plugin/src/site/site.xml     |  35 --
 featuremodel/pom.xml                               |  70 ---
 173 files changed, 20034 deletions(-)

diff --git a/featuremodel/feature-analyser/pom.xml b/featuremodel/feature-analyser/pom.xml
deleted file mode 100644
index add7b59..0000000
--- a/featuremodel/feature-analyser/pom.xml
+++ /dev/null
@@ -1,159 +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.analyser</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-
-    <name>Apache Sling Feature Analyser</name>
-    <description>
-        A feature describes an OSGi system
-    </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-analyser</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-analyser</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-analyser</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                <execution>
-                    <id>unpack-dependencies</id>
-                    <phase>prepare-package</phase>
-                    <goals>
-                        <goal>unpack-dependencies</goal>
-                    </goals>
-                    <configuration>
-                        <excludes>META-INF/**</excludes>
-                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
-                        <overWriteReleases>false</overWriteReleases>
-                        <overWriteSnapshots>true</overWriteSnapshots>
-                        <includeArtifactIds>org.apache.felix.converter,org.apache.sling.feature,org.apache.sling.commons.johnzon,osgi.core,slf4j-api,slf4j-simple</includeArtifactIds>
-                    </configuration>
-                </execution>
-            </executions>
-            </plugin>
-                <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifest>
-                            <mainClass>org.apache.sling.feature.analyser.main.Main</mainClass>
-                        </manifest>
-                    </archive>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.rat</groupId>
-                <artifactId>apache-rat-plugin</artifactId>
-                <configuration>
-                    <excludes>
-                        <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask</exclude>
-                        <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner</exclude>
-                        <exclude>src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner</exclude>
-                    </excludes>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-    <dependencies>
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>2.6</version>
-        </dependency>
-        <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.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>provided</scope>
-        </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.sling</groupId>
-            <artifactId>org.apache.sling.commons.johnzon</artifactId>
-            <version>1.0.0</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>
-        
-        <!-- Testing -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java
deleted file mode 100644
index 8124c9b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/Analyser.java
+++ /dev/null
@@ -1,125 +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.analyser;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.apache.sling.feature.scanner.Scanner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Analyser {
-
-    private final AnalyserTask[] tasks;
-
-    private final Scanner scanner;
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    public Analyser(final Scanner scanner,
-            final AnalyserTask...tasks)
-    throws IOException {
-        this.tasks = tasks;
-        this.scanner = scanner;
-    }
-
-    public Analyser(final Scanner scanner,
-            final String... taskIds)
-    throws IOException {
-        this(scanner, getTasks(taskIds));
-        if ( this.tasks.length != taskIds.length ) {
-            throw new IOException("Couldn't find all tasks " + taskIds);
-        }
-    }
-
-    public Analyser(final Scanner scanner)
-    throws IOException {
-        this(scanner, getTasks((String[])null));
-    }
-
-    private static AnalyserTask[] getTasks(final String... taskIds) {
-        final Set<String> ids = taskIds == null ? null : new HashSet<>(Arrays.asList(taskIds));
-        final ServiceLoader<AnalyserTask> loader = ServiceLoader.load(AnalyserTask.class);
-        final List<AnalyserTask> list = new ArrayList<>();
-        for(final AnalyserTask task : loader) {
-            if ( ids == null || ids.contains(task.getId()) ) {
-                list.add(task);
-            }
-        }
-        return list.toArray(new AnalyserTask[list.size()]);
-    }
-
-    public void analyse(final Application app)
-    throws Exception {
-        logger.info("Starting application analyzer...");
-
-        final ApplicationDescriptor appDesc = scanner.scan(app);
-
-        final List<String> warnings = new ArrayList<>();
-        final List<String> errors = new ArrayList<>();
-
-        // execute analyser tasks
-        for(final AnalyserTask task : tasks) {
-            logger.info("- Executing {}...", task.getName());
-            task.execute(new AnalyserTaskContext() {
-
-                @Override
-                public Application getApplication() {
-                    return app;
-                }
-
-                @Override
-                public ApplicationDescriptor getDescriptor() {
-                    return appDesc;
-                }
-
-                @Override
-                public void reportWarning(final String message) {
-                    warnings.add(message);
-                }
-
-                @Override
-                public void reportError(final String message) {
-                    errors.add(message);
-                }
-            });
-        }
-
-        for(final String msg : warnings) {
-            logger.warn(msg);
-        }
-        for(final String msg : errors) {
-            logger.error(msg);
-        }
-
-        if ( !errors.isEmpty() ) {
-            throw new Exception("Analyser detected errors. See log output for error messages.");
-        }
-
-        logger.info("Provisioning model analyzer finished");
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
deleted file mode 100644
index 79cc35b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/main/Main.java
+++ /dev/null
@@ -1,74 +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.analyser.main;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.analyser.Analyser;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.IOUtils;
-import org.apache.sling.feature.io.json.ApplicationJSONReader;
-import org.apache.sling.feature.scanner.Scanner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-public class Main {
-
-    public static void main(final String[] args) {
-        // setup logging
-        System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
-        System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
-        System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
-        System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
-
-        final Logger logger = LoggerFactory.getLogger("analyser");
-        logger.info("Apache Sling Application Analyser");
-        logger.info("");
-
-        if ( args.length == 0 ) {
-            logger.error("Required argument missing: application file");
-            System.exit(1);
-        }
-        if ( args.length > 1 ) {
-            logger.error("Too many arguments. Only one (application file) is supported");
-            System.exit(1);
-        }
-        final File f = new File(args[0]);
-        Application app = null;
-        try ( final FileReader r = new FileReader(f)) {
-            app = ApplicationJSONReader.read(r);
-        } catch ( final IOException ioe) {
-            logger.error("Unable to read application: {}", f, ioe);
-            System.exit(1);
-        }
-        if ( app.getFramework() == null ) {
-            app.setFramework(IOUtils.getFelixFrameworkId(null));
-        }
-
-        try {
-            final Scanner scanner = new Scanner(new ArtifactManagerConfig());
-            final Analyser analyser = new Analyser(scanner);
-            analyser.analyse(app);
-        } catch ( final Exception e) {
-            logger.error("Unable to analyse application: {}", f, e);
-            System.exit(1);
-        }
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java
deleted file mode 100644
index 3042a56..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.analyser;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java
deleted file mode 100644
index 97cd99a..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.analyser.task;
-
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * A analyser task analyses a specific part of the assembled
- * application. It can report errors and warnings.
- */
-@ConsumerType
-public interface AnalyserTask {
-
-    /** A unique (short) id. */
-    default String getId() {
-        return getClass().getName();
-    };
-
-    /** A human readable name to identify the task. */
-    default String getName() {
-        return getClass().getSimpleName();
-    };
-
-    /** Execute the task. */
-    void execute(AnalyserTaskContext ctx) throws Exception;
-}
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java
deleted file mode 100644
index b33fd80..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTaskContext.java
+++ /dev/null
@@ -1,51 +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.analyser.task;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.osgi.annotation.versioning.ProviderType;
-
-@ProviderType
-public interface AnalyserTaskContext {
-
-    /**
-     * The assembled application.
-     * @return The application.
-     */
-    Application getApplication();
-
-    /**
-     * The application descriptor
-     */
-    ApplicationDescriptor getDescriptor();
-
-    /**
-     * This method is invoked by a {@link AnalyserTask} to report
-     * a warning.
-     * @param message The message.
-     */
-    void reportWarning(String message);
-
-    /**
-     * This method is invoked by a {@link AnalyserTask} to report
-     * an error.
-     * @param message The message.
-     */
-    void reportError(String message);
-}
-
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
deleted file mode 100644
index 6a44c97..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundleExportsImports.java
+++ /dev/null
@@ -1,218 +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.analyser.task.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-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.scanner.PackageInfo;
-import org.osgi.framework.Version;
-
-public class CheckBundleExportsImports implements AnalyserTask {
-
-    @Override
-    public String getName() {
-        return "Bundle Import/Export Check";
-    }
-
-    @Override
-    public String getId() {
-        return "bundle-packages";
-    }
-
-    public static final class Report {
-
-        public List<PackageInfo> exportWithoutVersion = new ArrayList<>();
-
-        public List<PackageInfo> exportMatchingSeveral = new ArrayList<>();
-
-        public List<PackageInfo> importWithoutVersion = new ArrayList<>();
-
-        public List<PackageInfo> missingExports = new ArrayList<>();
-
-        public List<PackageInfo> missingExportsWithVersion = new ArrayList<>();
-
-        public List<PackageInfo> missingExportsForOptional = new ArrayList<>();
-    }
-
-    private Report getReport(final Map<BundleDescriptor, Report> reports, final BundleDescriptor info) {
-        Report report = reports.get(info);
-        if ( report == null ) {
-            report = new Report();
-            reports.put(info, report);
-        }
-        return report;
-    }
-
-    private void checkForVersionOnExportedPackages(final AnalyserTaskContext ctx, final Map<BundleDescriptor, Report> reports) {
-        for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
-            if ( info.getExportedPackages() != null ) {
-                for(final PackageInfo i : info.getExportedPackages()) {
-                    if ( i.getPackageVersion().compareTo(Version.emptyVersion) == 0 ) {
-                        getReport(reports, info).exportWithoutVersion.add(i);
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkForVersionOnImportingPackages(final AnalyserTaskContext ctx, final Map<BundleDescriptor, Report> reports) {
-        for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
-            if ( info.getImportedPackages() != null ) {
-                for(final PackageInfo i : info.getImportedPackages()) {
-                    if ( i.getVersion() == null ) {
-                        // don't report for javax and org.w3c. packages (TODO)
-                        if ( !i.getName().startsWith("javax.")
-                             && !i.getName().startsWith("org.w3c.")) {
-                            getReport(reports, info).importWithoutVersion.add(i);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public void execute(final AnalyserTaskContext ctx) throws IOException {
-        // basic checks
-        final Map<BundleDescriptor, Report> reports = new HashMap<>();
-        checkForVersionOnExportedPackages(ctx, reports);
-        checkForVersionOnImportingPackages(ctx, reports);
-
-        final SortedMap<Integer, List<BundleDescriptor>> bundlesMap = new TreeMap<>();
-        for(final BundleDescriptor bi : ctx.getDescriptor().getBundleDescriptors()) {
-            List<BundleDescriptor> list = bundlesMap.get(bi.getBundleStartLevel());
-            if ( list == null ) {
-                list = new ArrayList<>();
-                bundlesMap.put(bi.getBundleStartLevel(), list);
-            }
-            list.add(bi);
-        }
-
-        // add all system packages
-        final List<BundleDescriptor> exportingBundles = new ArrayList<>();
-        exportingBundles.add(ctx.getDescriptor().getFrameworkDescriptor());
-
-        for(final Map.Entry<Integer, List<BundleDescriptor>> entry : bundlesMap.entrySet()) {
-            // first add all exporting bundles
-            for(final BundleDescriptor info : entry.getValue()) {
-                if ( info.getExportedPackages() != null ) {
-                    exportingBundles.add(info);
-                }
-            }
-            // check importing bundles
-            for(final BundleDescriptor info : entry.getValue()) {
-                if ( info.getImportedPackages() != null ) {
-                    for(final PackageInfo pck : info.getImportedPackages() ) {
-                        final List<BundleDescriptor> candidates = getCandidates(exportingBundles, pck);
-                        if ( candidates.isEmpty() ) {
-                            if ( pck.isOptional() ) {
-                                getReport(reports, info).missingExportsForOptional.add(pck);
-                            } else {
-                                getReport(reports, info).missingExports.add(pck);
-                            }
-                        } else {
-                            final List<BundleDescriptor> matchingCandidates = new ArrayList<>();
-                            for(final BundleDescriptor i : candidates) {
-                                if ( i.isExportingPackage(pck) ) {
-                                    matchingCandidates.add(i);
-                                }
-                            }
-                            if ( matchingCandidates.isEmpty() ) {
-                                if ( pck.isOptional() ) {
-                                    getReport(reports, info).missingExportsForOptional.add(pck);
-                                } else {
-                                    getReport(reports, info).missingExportsWithVersion.add(pck);
-                                }
-                            } else if ( matchingCandidates.size() > 1 ) {
-                                getReport(reports, info).exportMatchingSeveral.add(pck);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        for(final Map.Entry<BundleDescriptor, Report> entry : reports.entrySet()) {
-            final String key = "Bundle " + entry.getKey().getArtifact().getId().getArtifactId() + ":" + entry.getKey().getArtifact().getId().getVersion();
-
-            if ( !entry.getValue().importWithoutVersion.isEmpty() ) {
-                ctx.reportWarning(key + " is importing package(s) " + getPackageInfo(entry.getValue().importWithoutVersion, false) + " without specifying a version range.");
-            }
-            if ( !entry.getValue().exportWithoutVersion.isEmpty() ) {
-                ctx.reportWarning(key + " is exporting package(s) " + getPackageInfo(entry.getValue().importWithoutVersion, false) + " without a version.");
-            }
-
-            if ( !entry.getValue().missingExports.isEmpty() ) {
-                ctx.reportError(key + " is importing package(s) " + getPackageInfo(entry.getValue().missingExports, false) + " in start level " +
-                        String.valueOf(entry.getKey().getBundleStartLevel()) + " but no bundle is exporting these for that start level.");
-            }
-            if ( !entry.getValue().missingExportsWithVersion.isEmpty() ) {
-                ctx.reportError(key + " is importing package(s) " + getPackageInfo(entry.getValue().missingExportsWithVersion, true) + " in start level " +
-                        String.valueOf(entry.getKey().getBundleStartLevel()) + " but no bundle is exporting these for that start level in the required version range.");
-            }
-        }
-    }
-
-    private String getPackageInfo(final List<PackageInfo> pcks, final boolean includeVersion) {
-        if ( pcks.size() == 1 ) {
-            if (includeVersion) {
-                return pcks.get(0).toString();
-            } else {
-                return pcks.get(0).getName();
-            }
-        }
-        final StringBuilder sb = new StringBuilder();
-        boolean first = true;
-        sb.append('[');
-        for(final PackageInfo info : pcks) {
-            if ( first ) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            if (includeVersion) {
-                sb.append(info.toString());
-            } else {
-                sb.append(info.getName());
-            }
-        }
-        sb.append(']');
-        return sb.toString();
-    }
-
-    private List<BundleDescriptor> getCandidates(final List<BundleDescriptor> exportingBundles, final PackageInfo pck) {
-        final List<BundleDescriptor> candidates = new ArrayList<>();
-        for(final BundleDescriptor info : exportingBundles) {
-            if ( info.isExportingPackage(pck.getName()) ) {
-                candidates.add(info);
-            }
-        }
-        return candidates;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java
deleted file mode 100644
index d5e2360..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForInitialContent.java
+++ /dev/null
@@ -1,85 +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.analyser.task.impl;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.Manifest;
-
-public class CheckBundlesForInitialContent implements AnalyserTask {
-
-    /** The manifest header to specify initial content to be loaded. */
-    private static final String CONTENT_HEADER = "Sling-Initial-Content";
-
-    /**
-     * The path directive specifying the target node where initial content will
-     * be loaded.
-     */
-    private static final String PATH_DIRECTIVE = "path";
-
-    @Override
-    public String getName() {
-        return "Bundle Initial Content Check";
-    }
-
-    @Override
-    public String getId() {
-        return "bundle-content";
-    }
-
-    @Override
-    public void execute(final AnalyserTaskContext ctx) {
-        // check for initial content
-        for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
-            final List<String> initialContent = extractInitialContent(info.getManifest());
-
-            if ( !initialContent.isEmpty() ) {
-                ctx.reportWarning("Found initial content in " + info.getArtifact() + " : " + initialContent);
-            }
-        }
-    }
-
-    private List<String> extractInitialContent(final Manifest m) {
-        final List<String> initialContent = new ArrayList<>();
-        if ( m != null ) {
-            final String root =  m.getMainAttributes().getValue(CONTENT_HEADER);
-            if (root != null) {
-                Clause[] clauses = Parser.parseHeader(root);
-                for (final Clause entry :clauses) {
-
-                    String path = entry.getDirective(PATH_DIRECTIVE);
-                    if (path == null) {
-                        path = "/";
-                    } else if (!path.startsWith("/")) {
-                        // make relative path absolute
-                        path = "/" + path;
-                    }
-                    initialContent.add(path);
-                }
-            }
-        }
-        return initialContent;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java
deleted file mode 100644
index 545244e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckBundlesForResources.java
+++ /dev/null
@@ -1,82 +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.analyser.task.impl;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.sling.feature.analyser.task.AnalyserTask;
-import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.Manifest;
-
-public class CheckBundlesForResources implements AnalyserTask {
-
-    /** The manifest header to specify bundle resources. */
-    private static final String BUNDLE_RESOURCE_ROOTS = "Sling-Bundle-Resources";
-
-    /**
-     * The path directive specifying the target node where initial content will
-     * be loaded.
-     */
-    private static final String PATH_DIRECTIVE = "path";
-
-    @Override
-    public String getName() {
-        return "Bundle Resources Check";
-    }
-
-    @Override
-    public String getId() {
-        return "bundle-resources";
-    }
-
-    @Override
-    public void execute(final AnalyserTaskContext ctx) {
-        // check for initial content
-        for(final BundleDescriptor info : ctx.getDescriptor().getBundleDescriptors()) {
-            final List<String> bundleResources = extractBundleResources(info.getManifest());
-            if ( !bundleResources.isEmpty() ) {
-                ctx.reportWarning("Found bundle resources in " + info.getArtifact() + " : " + bundleResources);
-            }
-        }
-    }
-
-    private List<String> extractBundleResources(final Manifest m) {
-        final List<String> bundleResources = new ArrayList<>();
-        if ( m != null ) {
-            final String root =  m.getMainAttributes().getValue(BUNDLE_RESOURCE_ROOTS);
-            if (root != null) {
-                Clause[] clauses = Parser.parseHeader(root);
-                for (final Clause entry : clauses) {
-                    final String resourceRoot = entry.getName();
-                    final String pathDirective = entry.getDirective(PATH_DIRECTIVE);
-                    if (pathDirective != null) {
-                        bundleResources.add(resourceRoot + "!" + pathDirective);
-                    } else {
-                        bundleResources.add(resourceRoot);
-                    }
-                }
-            }
-        }
-        return bundleResources;
-    }
-}
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
deleted file mode 100644
index bd1732f..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/impl/CheckRequirementsCapabilities.java
+++ /dev/null
@@ -1,110 +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.analyser.task.impl;
-
-import org.apache.felix.utils.resource.CapabilitySet;
-import org.apache.felix.utils.resource.RequirementImpl;
-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;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-
-public class CheckRequirementsCapabilities implements AnalyserTask {
-    private final String format = "Artifact %s:%s requires %s in start level %d but %s";
-
-    @Override
-    public void execute(AnalyserTaskContext ctx) throws Exception {
-        final SortedMap<Integer, List<ArtifactDescriptor>> artifactsMap = new TreeMap<>();
-        for(final BundleDescriptor bi : ctx.getDescriptor().getBundleDescriptors()) {
-            List<ArtifactDescriptor> list = artifactsMap.get(bi.getBundleStartLevel());
-            if ( list == null ) {
-                list = new ArrayList<>();
-                artifactsMap.put(bi.getBundleStartLevel(), list);
-            }
-            list.add(bi);
-        }
-
-        if (!ctx.getDescriptor().getArtifactDescriptors().isEmpty()) {
-            artifactsMap.put(
-                    (artifactsMap.isEmpty() ? 0 : artifactsMap.lastKey()) + 1,
-                    new ArrayList<>(ctx.getDescriptor().getArtifactDescriptors())
-                    );
-        }
-
-        // add system artifact
-        final List<ArtifactDescriptor> artifacts = new ArrayList<>();
-        artifacts.add(ctx.getDescriptor().getFrameworkDescriptor());
-
-        for(final Map.Entry<Integer, List<ArtifactDescriptor>> entry : artifactsMap.entrySet()) {
-            // first add all providing artifacts
-            for (final ArtifactDescriptor info : entry.getValue()) {
-                if (info.getCapabilities() != null) {
-                    artifacts.add(info);
-                }
-            }
-            // check requiring artifacts
-            for (final ArtifactDescriptor info : entry.getValue()) {
-                if (info.getRequirements() != null)
-                {
-                    for (Requirement requirement : info.getRequirements()) {
-                        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 (!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."));
-                                }
-                            }
-                            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."));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private List<ArtifactDescriptor> getCandidates(List<ArtifactDescriptor> artifactDescriptors, Requirement requirement) {
-        return artifactDescriptors.stream()
-                .filter(artifactDescriptor -> artifactDescriptor.getCapabilities() != null)
-                .filter(artifactDescriptor -> artifactDescriptor.getCapabilities().stream().anyMatch(capability -> CapabilitySet.matches(capability, requirement)))
-                .collect(Collectors.toList());
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java
deleted file mode 100644
index d265303..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/analyser/task/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.analyser.task;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java
deleted file mode 100644
index 5dabc64..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ApplicationDescriptor.java
+++ /dev/null
@@ -1,39 +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.scanner;
-
-import org.apache.sling.feature.Application;
-
-/**
- * Information about an application.
- * This is the aggregated information.
- */
-public abstract class ApplicationDescriptor extends ContainerDescriptor {
-
-    public abstract Application getApplication();
-
-    public abstract BundleDescriptor getFrameworkDescriptor();
-
-    @Override
-    public void lock() {
-        if ( this.isLocked() ) {
-            return;
-        }
-        this.aggregate(this.getFrameworkDescriptor());
-        super.lock();
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java
deleted file mode 100644
index 988b9d0..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ArtifactDescriptor.java
+++ /dev/null
@@ -1,39 +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.scanner;
-
-import java.io.File;
-
-import org.apache.sling.feature.Artifact;
-
-/**
- * Information about an artifact
- */
-public abstract class ArtifactDescriptor extends Descriptor {
-
-    /**
-     * Get the artifact file
-     * @return The artifact file
-     */
-    public abstract File getArtifactFile();
-
-    /**
-     * Get the artifact
-     * @return The artifact
-     */
-    public abstract Artifact getArtifact();
-}
\ No newline at end of file
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
deleted file mode 100644
index 52f3a71..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/BundleDescriptor.java
+++ /dev/null
@@ -1,94 +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.scanner;
-
-import java.util.jar.Manifest;
-
-import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-
-/**
- * Information about a bundle
- */
-public abstract class BundleDescriptor extends ArtifactDescriptor implements Comparable<BundleDescriptor> {
-
-    /**
-     * Get the bundle symbolic name.
-     * @return The bundle symbolic name
-     */
-    public abstract String getBundleSymbolicName();
-
-    /**
-     * Get the bundle version
-     * @return The bundle version
-     */
-    public abstract String getBundleVersion();
-
-    /**
-     * Get the start level
-     * @return The start level.
-     */
-    public abstract int getBundleStartLevel();
-
-    /**
-     * If the artifact has a manifest, return it
-     * @return The manifest
-     */
-    public abstract Manifest getManifest();
-
-    public boolean isExportingPackage(final String packageName) {
-        for(final PackageInfo i : getExportedPackages()) {
-            if ( i.getName().equals(packageName) ) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean isExportingPackage(final PackageInfo info) {
-        for(final PackageInfo i : getExportedPackages()) {
-            if ( i.getName().equals(info.getName())
-                 && (info.getVersion() == null || info.getPackageVersionRange().includes(i.getPackageVersion()))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if ( obj instanceof BundleDescriptorImpl ) {
-            return this.getBundleSymbolicName().equals(((BundleDescriptorImpl)obj).getBundleSymbolicName()) && this.getBundleVersion().equals(((BundleDescriptorImpl)obj).getBundleVersion());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return (this.getBundleSymbolicName() + ':' + this.getBundleVersion()).hashCode();
-
-    }
-
-    @Override
-    public String toString() {
-        return "BundleInfo [symbolicName=" + getBundleSymbolicName() + ", version=" + this.getBundleVersion() + "]";
-    }
-
-    @Override
-    public int compareTo(final BundleDescriptor o) {
-        return (this.getBundleSymbolicName() + ':' + this.getBundleVersion()).compareTo((o.getBundleSymbolicName() + ':' + o.getBundleVersion()));
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java
deleted file mode 100644
index 0ae37f3..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/ContainerDescriptor.java
+++ /dev/null
@@ -1,70 +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.scanner;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Information about a container (feature/application).
- * This is the aggregated information.
- */
-public abstract class ContainerDescriptor extends Descriptor {
-
-    private final Set<BundleDescriptor> bundles = new HashSet<>();
-
-    private final Set<ArtifactDescriptor> artifacts = new HashSet<>();
-
-    /**
-     * Return a set of bundle descriptors.
-     *
-     * The requirements and capabilities of the returned bundles are
-     * available as an aggregate from {@link Descriptor#getCapabilities()},
-     * {@link Descriptor#getRequirements()}, {@link Descriptor#getDynamicImportedPackages()}
-     * {@link Descriptor#getExportedPackages()} and {@link Descriptor#getImportedPackages()}
-     * @return The set of bundle descriptors (might be empty)
-     */
-    public final Set<BundleDescriptor> getBundleDescriptors() {
-        return this.isLocked() ? Collections.unmodifiableSet(bundles) : bundles;
-    }
-
-    /**
-     * Return a set of artifact descriptors
-     * The requirements and capabilities of the returned artifacts are
-     * available as an aggregate from {@link Descriptor#getCapabilities()},
-     * {@link Descriptor#getRequirements()}.
-     * @return The set of artifact descriptors (might be empty)
-     */
-    public final Set<ArtifactDescriptor> getArtifactDescriptors() {
-        return this.isLocked() ? Collections.unmodifiableSet(artifacts) : artifacts;
-    }
-
-    @Override
-    public void lock() {
-        if ( this.isLocked() ) {
-            return;
-        }
-        for(final BundleDescriptor bd : this.bundles) {
-            this.aggregate(bd);
-        }
-        for(final ArtifactDescriptor d : this.artifacts) {
-            this.aggregate(d);
-        }
-        super.lock();
-    }
-}
\ No newline at end of file
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
deleted file mode 100644
index 2b5fc1b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Descriptor.java
+++ /dev/null
@@ -1,92 +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.scanner;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-/**
- * A descriptor holds information about requirements and capabilities
- */
-public abstract class Descriptor  {
-
-    private boolean locked;
-
-    private final Set<PackageInfo> exports = new HashSet<>();
-
-    private final Set<PackageInfo> imports = new HashSet<>();
-
-    private final Set<PackageInfo> dynImports = new HashSet<>();
-
-    private final Set<Requirement> reqs = new HashSet<>();
-
-    private final Set<Capability> caps = new HashSet<>();
-
-    public void lock() {
-        this.locked = true;
-    }
-
-    public final boolean isLocked() {
-        return this.locked;
-    }
-
-    protected void checkLocked() {
-        if (this.locked) {
-            throw new IllegalStateException("Descriptor is locked.");
-        }
-    }
-
-    protected void aggregate(final Descriptor d) {
-        reqs.addAll(d.getRequirements());
-        caps.addAll(d.getCapabilities());
-        dynImports.addAll(d.getDynamicImportedPackages());
-        imports.addAll(d.getImportedPackages());
-        exports.addAll(d.getExportedPackages());
-    }
-
-    public final Set<PackageInfo> getExportedPackages() {
-        return locked ? Collections.unmodifiableSet(exports) : exports;
-    }
-
-    public final Set<PackageInfo> getImportedPackages() {
-        return locked ? Collections.unmodifiableSet(imports) : imports;
-    }
-
-    public final Set<PackageInfo> getDynamicImportedPackages() {
-        return locked ? Collections.unmodifiableSet(dynImports) : dynImports;
-    }
-
-    /**
-     * Return the list of requirements.
-     * @return The list of requirements. The list might be empty.
-     */
-    public final Set<Requirement> getRequirements() {
-        return locked ? Collections.unmodifiableSet(reqs) : reqs;
-    }
-
-    /**
-     * Return the list of capabilities.
-     * @return The list of capabilities. The list might be empty.
-     */
-    public final Set<Capability> getCapabilities() {
-        return locked ?  Collections.unmodifiableSet(caps) : caps;
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java
deleted file mode 100644
index d82b6f1..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/FeatureDescriptor.java
+++ /dev/null
@@ -1,28 +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.scanner;
-
-import org.apache.sling.feature.Feature;
-
-/**
- * Information about a feature.
- * This is the aggregated information.
- */
-public abstract class FeatureDescriptor extends ContainerDescriptor {
-
-    public abstract Feature getFeature();
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
deleted file mode 100644
index bb7081b..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/PackageInfo.java
+++ /dev/null
@@ -1,110 +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.scanner;
-
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-
-public class PackageInfo implements Comparable<PackageInfo> {
-
-    private final boolean optional;
-    private final String name;
-    private final String version;
-
-    public PackageInfo(final String name, final String version, final boolean optional) {
-        this.name = name;
-        this.version = version;
-        this.optional = optional;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public boolean isOptional() {
-        return optional;
-    }
-
-    public Version getPackageVersion() {
-        if (this.version == null)
-            return null;
-
-        return new Version(this.version);
-    }
-
-    public VersionRange getPackageVersionRange() {
-        if (this.version == null)
-            return null;
-
-        return new VersionRange(this.version);
-    }
-
-    @Override
-    public String toString() {
-        return "Package " + name
-                + ";version=" + version
-                + (this.optional ? " (optional)" : "");
-    }
-
-    @Override
-    public int compareTo(final PackageInfo o) {
-        int result = this.name.compareTo(o.name);
-        if ( result == 0 ) {
-            result = this.version.compareTo(o.version);
-        }
-        return result;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((name == null) ? 0 : name.hashCode());
-        result = prime * result + (optional ? 1231 : 1237);
-        result = prime * result + ((version == null) ? 0 : version.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        PackageInfo other = (PackageInfo) obj;
-        if (name == null) {
-            if (other.name != null)
-                return false;
-        } else if (!name.equals(other.name))
-            return false;
-        if (optional != other.optional)
-            return false;
-        if (version == null) {
-            if (other.version != null)
-                return false;
-        } else if (!version.equals(other.version))
-            return false;
-        return true;
-    }
-
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java
deleted file mode 100644
index b0c29a9..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/Scanner.java
+++ /dev/null
@@ -1,223 +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.scanner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.scanner.impl.ApplicationDescriptorImpl;
-import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
-import org.apache.sling.feature.scanner.impl.FeatureDescriptorImpl;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-import org.apache.sling.feature.scanner.spi.FrameworkScanner;
-
-/**
- * The scanner is a service that scans items and provides descriptions for these.
- * The following items can be scanned individually
- * <ul>
- *   <li>A bundle artifact
- *   <li>An extension (requires {@link ExtensionScanner}s)
- *   <li>A feature (requires {@link ExtensionScanner}s)
- *   <li>A framework (requires {@link FrameworkScanner}s)
- *   <li>An application (requires all scanner types)
- * </ul>
- */
-public class Scanner {
-
-    private final ArtifactManager artifactManager;
-
-    private final List<ExtensionScanner> extensionScanners;
-
-    private final List<FrameworkScanner> frameworkScanners;
-
-    /**
-     * Create a new scanner
-     *
-     * @param amConfig The artifact manager configuration
-     * @param artifactScanners A list of artifact scanners
-     * @param extensionScanners A list of extension scanners
-     * @param frameworkScanners A list of framework scanners
-     * @throws IOException If something goes wrong
-     */
-    public Scanner(final ArtifactManagerConfig amConfig,
-            final List<ExtensionScanner> extensionScanners,
-            final List<FrameworkScanner> frameworkScanners)
-    throws IOException {
-        this.artifactManager = ArtifactManager.getArtifactManager(amConfig);
-        this.extensionScanners = extensionScanners == null ? getServices(ExtensionScanner.class) : extensionScanners;
-        this.frameworkScanners = frameworkScanners == null ? getServices(FrameworkScanner.class) : frameworkScanners;
-    }
-
-    /**
-     * Create a new scanner and use the service loader to find the scanners
-     *
-     * @param amConfig The artifact manager configuration
-     * @throws IOException If something goes wrong
-     */
-    public Scanner(final ArtifactManagerConfig amConfig)
-    throws IOException {
-        this(amConfig, null, null);
-    }
-
-    /**
-     * Get services from the service loader
-     *
-     * @param clazz The service class
-     * @return The list of services might be empty.
-     */
-    private static <T> List<T> getServices(final Class<T> clazz) {
-        final ServiceLoader<T> loader = ServiceLoader.load(clazz);
-        final List<T> list = new ArrayList<>();
-        for(final T task : loader) {
-            list.add(task);
-        }
-        return list;
-    }
-
-    /**
-     * Scan a bundle
-     *
-     * @param bundle The bundle artifact
-     * @param startLevel The start level of the bundle
-     * @return The bundle descriptor
-     * @throws IOException If something goes wrong or the provided artifact is not a bundle.
-     */
-    public BundleDescriptor scan(final Artifact bundle, final int startLevel) throws IOException {
-        final File file = artifactManager.getArtifactHandler(bundle.getId().toMvnUrl()).getFile();
-        if ( file == null ) {
-            throw new IOException("Unable to find file for " + bundle.getId());
-        }
-
-        return new BundleDescriptorImpl(bundle, file, startLevel);
-    }
-
-    /**
-     * Get all bundle descriptors for a feature / application
-     * @param bundles The bundles
-     * @param desc The descriptor
-     * @throws IOException If something goes wrong or no suitable scanner is found.
-     */
-    private void getBundleInfos(final Bundles bundles, final ContainerDescriptor desc)
-    throws IOException {
-        for(final Map.Entry<Integer, List<Artifact>> entry : bundles.getBundlesByStartOrder().entrySet()) {
-            for(final Artifact bundle : entry.getValue() ) {
-                final BundleDescriptor bundleDesc = scan(bundle, entry.getKey());
-                desc.getBundleDescriptors().add(bundleDesc);
-            }
-        }
-    }
-
-    private void scan(final Extensions extensions, final ContainerDescriptor desc)
-    throws IOException {
-        for(final Extension ext : extensions) {
-            ContainerDescriptor extDesc = null;
-            for(final ExtensionScanner scanner : this.extensionScanners) {
-                extDesc = scanner.scan(ext, this.artifactManager);
-                if ( extDesc != null ) {
-                    break;
-                }
-            }
-            if ( extDesc == null ) {
-                throw new IOException("No extension scanner found for extension named " + ext.getName() + " of type " + ext.getType().name());
-            }
-            desc.getRequirements().addAll(extDesc.getRequirements());
-            desc.getCapabilities().addAll(extDesc.getCapabilities());
-            desc.getExportedPackages().addAll(extDesc.getExportedPackages());
-            desc.getImportedPackages().addAll(extDesc.getImportedPackages());
-            desc.getDynamicImportedPackages().addAll(extDesc.getDynamicImportedPackages());
-
-            desc.getArtifactDescriptors().addAll(extDesc.getArtifactDescriptors());
-            desc.getBundleDescriptors().addAll(extDesc.getBundleDescriptors());
-        }
-    }
-
-    private void compact(final ContainerDescriptor desc) {
-        // TBD remove all import packages / dynamic import packages which are resolved by this bundle set
-        // same with requirements
-
-    }
-
-    /**
-     * Scan a feature
-     *
-     * @param feature The feature
-     * @return The feature descriptor
-     * @throws IOException If something goes wrong or a scanner is missing
-     */
-    public FeatureDescriptor scan(final Feature feature) throws IOException {
-        final FeatureDescriptorImpl desc = new FeatureDescriptorImpl(feature);
-
-        getBundleInfos(feature.getBundles(), desc);
-        scan(feature.getExtensions(), desc);
-
-        compact(desc);
-
-        desc.lock();
-
-        return desc;
-    }
-
-    /**
-     * Scan an application
-     *
-     * @param app The application
-     * @return The application descriptor
-     * @throws IOException If something goes wrong or a scanner is missing
-     */
-    public ApplicationDescriptor scan(final Application app) throws IOException {
-        final ApplicationDescriptorImpl desc = new ApplicationDescriptorImpl(app);
-
-        getBundleInfos(app.getBundles(), desc);
-        scan(app.getExtensions(), desc);
-
-        compact(desc);
-
-        // framework
-        final File file = artifactManager.getArtifactHandler(app.getFramework().toMvnUrl()).getFile();
-        if ( file == null ) {
-            throw new IOException("Unable to find file for " + app.getFramework());
-        }
-
-        BundleDescriptor fwk = null;
-        for(final FrameworkScanner scanner : this.frameworkScanners) {
-            fwk = scanner.scan(app.getFramework(), file, app.getFrameworkProperties());
-            if ( fwk != null ) {
-                break;
-            }
-        }
-        if ( fwk == null ) {
-            throw new IOException("No scanner found for framework " + app.getFramework().toMvnId());
-        }
-
-        desc.setFrameworkDescriptor(fwk);
-
-        desc.lock();
-        return desc;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java
deleted file mode 100644
index cf9248e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ApplicationDescriptorImpl.java
+++ /dev/null
@@ -1,52 +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.scanner.impl;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.scanner.ApplicationDescriptor;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-/**
- * Information about an application.
- * This is the aggregated information.
- */
-public class ApplicationDescriptorImpl
-    extends ApplicationDescriptor {
-
-    private BundleDescriptor frameworkDescriptor;
-
-    private final Application app;
-
-    public ApplicationDescriptorImpl(final Application app) {
-        this.app = app;
-    }
-
-    @Override
-    public Application getApplication() {
-        return this.app;
-    }
-
-    @Override
-    public BundleDescriptor getFrameworkDescriptor() {
-        return frameworkDescriptor;
-    }
-
-    public void setFrameworkDescriptor(final BundleDescriptor frameworkDescriptor) {
-        checkLocked();
-        this.frameworkDescriptor = frameworkDescriptor;
-    }
-}
\ No newline at end of file
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
deleted file mode 100644
index d933060..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ /dev/null
@@ -1,194 +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.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.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.scanner.PackageInfo;
-import org.osgi.framework.Constants;
-
-/**
- * Information about a bundle
- */
-public class BundleDescriptorImpl
-    extends BundleDescriptor {
-
-    /** The bundle symbolic name. */
-    private String symbolicName;
-
-    /** The bundle version. */
-    private String bundleVersion;
-
-    /** The start level of this artifact. */
-    private final int startLevel;
-
-    /** Manifest */
-    private final Manifest manifest;
-
-    /** The physical file for analyzing. */
-    private final File artifactFile;
-
-    /** The corresponding artifact from the feature. */
-    private final Artifact artifact;
-
-    public BundleDescriptorImpl(final Artifact a,
-            final File file,
-            final int startLevel) throws IOException  {
-        this.artifact = a;
-        this.artifactFile = file;
-        this.startLevel = startLevel;
-        try (final JarFile jarFile = new JarFile(this.artifactFile) ) {
-            this.manifest = jarFile.getManifest();
-        }
-        if ( this.manifest == null ) {
-            throw new IOException("File has no manifest");
-        }
-        this.analyze();
-        this.lock();
-    }
-
-    /**
-     * Get the bundle symbolic name.
-     * @return The bundle symbolic name
-     */
-    @Override
-    public String getBundleSymbolicName() {
-        return symbolicName;
-    }
-
-    /**
-     * Get the bundle version
-     * @return The bundle version
-     */
-    @Override
-    public String getBundleVersion() {
-        return bundleVersion;
-    }
-
-    /**
-     * Get the start level
-     * @return The start level or {@code 0} for the default.
-     */
-    @Override
-    public int getBundleStartLevel() {
-        return startLevel;
-    }
-
-    @Override
-    public File getArtifactFile() {
-        return artifactFile;
-    }
-
-    @Override
-    public Artifact getArtifact() {
-        return artifact;
-    }
-
-    @Override
-    public Manifest getManifest() {
-        return this.manifest;
-    }
-
-    protected void analyze() throws IOException {
-        final String name = this.manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
-        if ( name != null ) {
-            final String version = this.manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
-            if ( version == null ) {
-                throw new IOException("Unable to get bundle version from artifact " + getArtifact().getId().toMvnId());
-            }
-            this.symbolicName = name;
-            this.bundleVersion = version;
-            final String newBundleName = this.getArtifact().getMetadata().get("bundle:rename-bsn");
-            if (newBundleName != null) {
-                this.symbolicName = newBundleName;
-            }
-
-            this.getExportedPackages().addAll(extractExportedPackages(this.manifest));
-            this.getImportedPackages().addAll(extractImportedPackages(this.manifest));
-            this.getDynamicImportedPackages().addAll(extractDynamicImportedPackages(this.manifest));
-            try {
-                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);
-            }
-        } else {
-            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);
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java
deleted file mode 100644
index 9d67b1e..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageDescriptor.java
+++ /dev/null
@@ -1,142 +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.scanner.impl;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.scanner.ArtifactDescriptor;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-
-/**
- * Information about a content package.
- */
-public class ContentPackageDescriptor extends ArtifactDescriptor {
-
-    /** The content package name. */
-    private String name;
-
-    /** Bundles in the content package. */
-    public final List<BundleDescriptor> bundles = new ArrayList<>();
-
-    /** Configurations in the content package. */
-    public final List<Configuration> configs = new ArrayList<>();
-
-    private File artifactFile;
-
-    private Artifact artifact;
-
-    /**
-     * Get the artifact file
-     * @return The artifact file
-     */
-    @Override
-    public File getArtifactFile() {
-        return artifactFile;
-    }
-
-    /**
-     * Get the artifact
-     * @return The artifact
-     */
-    @Override
-    public Artifact getArtifact() {
-        return artifact;
-    }
-
-    /**
-     * Set the artifact
-     * @param artifact The artifact
-     */
-    public void setArtifact(Artifact artifact) {
-        checkLocked();
-        this.artifact = artifact;
-    }
-
-    /**
-     * Set the artifact file
-     * @param artifactFile The artifact file
-     */
-    public void setArtifactFile(File artifactFile) {
-        checkLocked();
-        this.artifactFile = artifactFile;
-    }
-
-    /** Optional: the artifact of the content package. */
-    private Artifact contentPackage;
-
-    /** Optional: the path inside of the content package. */
-    private String contentPath;
-
-    /**
-     * Get the content package
-     * @return The content package or {@code null}
-     */
-    public Artifact getContentPackage() {
-        return contentPackage;
-    }
-
-    /**
-     * Get the content path
-     * @return The content path or {@code null}
-     */
-    public String getContentPath() {
-        return this.contentPath;
-    }
-
-    /**
-     * Whether this artifact is embedded in a content package
-     * @return {@code true} if embedded.
-     */
-    public boolean isEmbeddedInContentPackage() {
-        return this.contentPath != null;
-    }
-
-    /**
-     * Set the information about the content package containing this artifact
-     * @param artifact The package
-     * @param path The path inside the package
-     */
-    public void setContentPackageInfo(final Artifact artifact, final String path) {
-        checkLocked();
-        this.contentPackage = artifact;
-        this.contentPath = path;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(final String value) {
-        checkLocked();
-        this.name = value;
-    }
-
-
-    public boolean hasEmbeddedArtifacts() {
-        return !this.bundles.isEmpty() || !this.configs.isEmpty();
-    }
-
-    @Override
-    public String toString() {
-        return "ContentPackage [" + name + "]";
-    }
-}
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java
deleted file mode 100644
index 5720166..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java
+++ /dev/null
@@ -1,357 +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.scanner.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ContentPackageScanner {
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    private final byte[] buffer = new byte[65536];
-
-    private enum FileType {
-        BUNDLE,
-        CONFIG,
-        PACKAGE
-    }
-
-    public Set<ContentPackageDescriptor> scan(final Artifact desc, final File file) throws IOException {
-        if (!file.getName().endsWith(".zip") ) {
-            throw new IOException("Artifact seems to be no content package (not a zip file): " + desc.getId().toMvnId());
-        }
-
-        final Set<ContentPackageDescriptor> contentPackages = new HashSet<>();
-        final ContentPackageDescriptor cp = new ContentPackageDescriptor();
-        final int lastDot = file.getName().lastIndexOf(".");
-        cp.setName(file.getName().substring(0, lastDot));
-        cp.setArtifact(desc);
-        cp.setArtifactFile(file);
-
-        extractContentPackage(cp, contentPackages, file);
-
-        contentPackages.add(cp);
-        cp.lock();
-
-        return contentPackages;
-    }
-
-    private void extractContentPackage(final ContentPackageDescriptor cp,
-            final Set<ContentPackageDescriptor> infos,
-            final File archive)
-    throws IOException {
-        logger.debug("Analyzing Content Package {}", archive.getName());
-
-        final File tempDir = Files.createTempDirectory(null).toFile();
-        try {
-            final File toDir = new File(tempDir, archive.getName());
-            toDir.mkdirs();
-
-            final List<File> toProcess = new ArrayList<>();
-
-            try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(archive)) ) {
-                boolean done = false;
-                while ( !done ) {
-                    final ZipEntry entry = zis.getNextEntry();
-                    if ( entry == null ) {
-                        done = true;
-                    } else {
-                        final String entryName = entry.getName();
-                        if ( !entryName.endsWith("/") && entryName.startsWith("jcr_root/") ) {
-                            final String contentPath = entryName.substring(8);
-
-                            FileType fileType = null;
-
-                            if ( entryName.endsWith(".zip") ) {
-                                // embedded content package
-                                fileType = FileType.PACKAGE;
-
-                                // check for libs or apps
-                            } else if ( entryName.startsWith("jcr_root/libs/") || entryName.startsWith("jcr_root/apps/") ) {
-
-                                // check if this is an install folder (I)
-                                // install folders are either named:
-                                // "install" or
-                                // "install.{runmode}"
-                                boolean isInstall = entryName.indexOf("/install/") != -1;
-                                if ( !isInstall ) {
-                                    final int pos = entryName.indexOf("/install.");
-                                    if ( pos != -1 ) {
-                                        final int endSlashPos = entryName.indexOf('/', pos + 1);
-                                        if ( endSlashPos != -1 ) {
-                                            isInstall = true;
-                                        }
-                                    }
-                                }
-                                if ( !isInstall ) {
-                                    // check if this is an install folder (II)
-                                    // config folders are either named:
-                                    // "config" or
-                                    // "config.{runmode}"
-                                    isInstall = entryName.indexOf("/config/") != -1;
-                                    if ( !isInstall ) {
-                                        final int pos = entryName.indexOf("/config.");
-                                        if ( pos != -1 ) {
-                                            final int endSlashPos = entryName.indexOf('/', pos + 1);
-                                            if ( endSlashPos != -1 ) {
-                                                isInstall = true;
-                                            }
-                                        }
-                                    }
-                                }
-
-                                if (isInstall ) {
-
-                                   if ( entryName.endsWith(".jar") ) {
-                                       fileType = FileType.BUNDLE;
-                                   } else if ( entryName.endsWith(".xml") || entryName.endsWith(".config") ) {
-                                       fileType = FileType.CONFIG;
-                                   }
-                                }
-                            }
-
-                            if ( fileType != null ) {
-                                logger.debug("- extracting : {}", entryName);
-                                final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
-                                newFile.getParentFile().mkdirs();
-
-                                try (final FileOutputStream fos = new FileOutputStream(newFile)) {
-                                    int len;
-                                    while ((len = zis.read(buffer)) > -1) {
-                                        fos.write(buffer, 0, len);
-                                    }
-                                }
-
-                                if ( fileType == FileType.BUNDLE ) {
-                                    int startLevel = 20;
-                                    final int lastSlash = contentPath.lastIndexOf('/');
-                                    final int nextSlash = contentPath.lastIndexOf('/', lastSlash - 1);
-                                    final String part = contentPath.substring(nextSlash + 1, lastSlash);
-                                    try {
-                                        startLevel = Integer.valueOf(part);
-                                    } catch ( final NumberFormatException ignore ) {
-                                        // ignore
-                                    }
-
-                                    final Artifact bundle = new Artifact(extractArtifactId(tempDir, newFile));
-                                    final BundleDescriptor info = new BundleDescriptorImpl(bundle, newFile, startLevel);
-                                    bundle.getMetadata().put("content-package", cp.getArtifact().getId().toMvnId());
-                                    bundle.getMetadata().put("content-path", contentPath);
-
-                                    cp.bundles.add(info);
-
-                                } else if ( fileType == FileType.CONFIG ) {
-
-                                    final Configuration configEntry = this.process(newFile, cp.getArtifact(), contentPath);
-                                    if ( configEntry != null ) {
-
-                                        cp.configs.add(configEntry);
-                                    }
-
-                                } else if ( fileType == FileType.PACKAGE ) {
-                                    toProcess.add(newFile);
-                                }
-
-                            }
-
-                        }
-                        zis.closeEntry();
-                    }
-                }
-
-            }
-
-            for(final File f : toProcess) {
-                extractContentPackage(cp, infos, f);
-                final ContentPackageDescriptor i = new ContentPackageDescriptor();
-                final int lastDot = f.getName().lastIndexOf(".");
-                i.setName(f.getName().substring(0, lastDot));
-                i.setArtifactFile(f);
-                i.setContentPackageInfo(cp.getArtifact(), f.getName());
-                infos.add(i);
-
-                i.lock();
-            }
-        } finally {
-            if ( tempDir.exists() ) {
-                tempDir.delete();
-            }
-        }
-    }
-
-    private ArtifactId extractArtifactId(final File tempDir, final File bundleFile)
-    throws IOException {
-        logger.debug("Extracting Bundle {}", bundleFile.getName());
-
-        final File toDir = new File(tempDir, bundleFile.getName());
-        toDir.mkdirs();
-
-        try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(bundleFile)) ) {
-            boolean done = false;
-            while ( !done ) {
-                final ZipEntry entry = zis.getNextEntry();
-                if ( entry == null ) {
-                    done = true;
-                } else {
-                    final String entryName = entry.getName();
-                    if ( !entryName.endsWith("/") && entryName.startsWith("META-INF/maven/") && entryName.endsWith("/pom.properties")) {
-                        logger.debug("- extracting : {}", entryName);
-                        final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
-                        newFile.getParentFile().mkdirs();
-
-                        try (final FileOutputStream fos = new FileOutputStream(newFile)) {
-                            int len;
-                            while ((len = zis.read(buffer)) > -1) {
-                                fos.write(buffer, 0, len);
-                            }
-                        }
-
-                    }
-                    zis.closeEntry();
-                }
-            }
-
-        }
-
-        // check for maven
-
-        final File metaInfDir = new File(toDir, "META-INF");
-        if ( metaInfDir.exists() ) {
-            final File mavenDir = new File(metaInfDir, "maven");
-            if ( mavenDir.exists() ) {
-                File groupDir = null;
-                for(final File d : mavenDir.listFiles()) {
-                    if ( d.isDirectory() && !d.getName().startsWith(".") ) {
-                        groupDir = d;
-                        break;
-                    }
-                }
-                if ( groupDir != null ) {
-                    File artifactDir = null;
-                    for(final File d : groupDir.listFiles()) {
-                        if ( d.isDirectory() && !d.getName().startsWith(".") ) {
-                            artifactDir = d;
-                            break;
-                        }
-                    }
-                    if ( artifactDir != null ) {
-                        final File propsFile = new File(artifactDir, "pom.properties");
-                        if ( propsFile.exists() ) {
-                            final Properties props = new Properties();
-                            try ( final Reader r = new FileReader(propsFile) ) {
-                                props.load(r);
-                            }
-                            String groupId = props.getProperty("groupId");
-                            String artifactId = props.getProperty("artifactId");
-                            String version = props.getProperty("version");
-                            String classifier = null;
-
-                            // Capture classifier
-                            final int pos = bundleFile.getName().indexOf(version) + version.length();
-                            if ( bundleFile.getName().charAt(pos) == '-') {
-                                classifier = bundleFile.getName().substring(pos + 1, bundleFile.getName().lastIndexOf('.'));
-                            }
-
-                            final String parts[] = version.split("\\.");
-                            if ( parts.length == 4 ) {
-                                final int lastDot = version.lastIndexOf('.');
-                                version = version.substring(0, lastDot) + '-' + version.substring(lastDot + 1);
-                            }
-
-                            if ( groupId != null && artifactId != null && version != null ) {
-                                return new ArtifactId(groupId,
-                                        artifactId,
-                                        version, classifier, null);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        throw new IOException(bundleFile.getName() + " has no maven coordinates!");
-    }
-
-    private Configuration process(final File configFile,
-            final Artifact packageArtifact,
-            final String contentPath)
-    throws IOException {
-
-        boolean isConfig = true;
-        if ( configFile.getName().endsWith(".xml") ) {
-            final String contents = Files.readAllLines(configFile.toPath()).toString();
-            if ( contents.indexOf("jcr:primaryType=\"sling:OsgiConfig\"") == -1 ) {
-                isConfig = false;
-            }
-        }
-
-        if ( isConfig ) {
-            final String id;
-            if ( ".content.xml".equals(configFile.getName()) ) {
-                final int lastSlash = contentPath.lastIndexOf('/');
-                final int previousSlash = contentPath.lastIndexOf('/', lastSlash - 1);
-                id = contentPath.substring(previousSlash + 1, lastSlash);
-            } else {
-                final int lastDot = configFile.getName().lastIndexOf('.');
-                id = configFile.getName().substring(0, lastDot);
-            }
-
-            final String pid, factoryPid;
-            final int slashPos = id.indexOf('-');
-            if ( slashPos == -1 ) {
-                pid = id;
-                factoryPid = null;
-            } else {
-                pid = id.substring(slashPos + 1);
-                factoryPid = id.substring(0, slashPos);
-            }
-
-            final Configuration cfg;
-            if ( factoryPid != null ) {
-                cfg = new Configuration(factoryPid, pid);
-            } else {
-                cfg = new Configuration(pid);
-            }
-            cfg.getProperties().put("content-path", contentPath);
-            cfg.getProperties().put("content-package", packageArtifact.getId().toMvnId());
-
-            return cfg;
-        }
-
-        return null;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java
deleted file mode 100644
index e125ce0..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/ContentPackagesExtensionScanner.java
+++ /dev/null
@@ -1,74 +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.scanner.impl;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-public class ContentPackagesExtensionScanner implements ExtensionScanner {
-
-    @Override
-    public String getId() {
-        return "content-packages";
-    }
-
-    @Override
-    public String getName() {
-        return "Content Packages Scanner";
-    }
-
-    @Override
-    public ContainerDescriptor scan(final Extension extension,
-            final ArtifactManager artifactManager)
-    throws IOException {
-        if (!FeatureConstants.EXTENSION_NAME_CONTENT_PACKAGES.equals(extension.getName()) ) {
-            return null;
-        }
-        if ( extension.getType() != ExtensionType.ARTIFACTS ) {
-            return null;
-        }
-
-        final ContentPackageScanner scanner = new ContentPackageScanner();
-        final ContainerDescriptor cd = new ContainerDescriptor() {};
-
-        for(final Artifact a : extension.getArtifacts()) {
-            final File file = artifactManager.getArtifactHandler(a.getId().toMvnUrl()).getFile();
-            if ( file == null ) {
-                throw new IOException("Unable to find file for " + a.getId());
-            }
-
-            final Set<ContentPackageDescriptor> pcks = scanner.scan(a, file);
-            for(final ContentPackageDescriptor desc : pcks) {
-                cd.getArtifactDescriptors().add(desc);
-                cd.getBundleDescriptors().addAll(desc.bundles);
-            }
-        }
-
-        cd.lock();
-
-        return cd;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java
deleted file mode 100644
index 63b2c1d..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FeatureDescriptorImpl.java
+++ /dev/null
@@ -1,39 +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.scanner.impl;
-
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.scanner.FeatureDescriptor;
-
-/**
- * Information about a feature.
- * This is the aggregated information.
- */
-public class FeatureDescriptorImpl
-    extends FeatureDescriptor {
-
-    private final Feature feature;
-
-    public FeatureDescriptorImpl(final Feature feature) {
-        this.feature = feature;
-    }
-
-    @Override
-    public Feature getFeature() {
-        return this.feature;
-    }
-}
\ 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
deleted file mode 100644
index 2bb2cde..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScanner.java
+++ /dev/null
@@ -1,201 +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.scanner.impl;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.Manifest;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.apache.commons.lang.text.StrLookup;
-import org.apache.commons.lang.text.StrSubstitutor;
-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.scanner.PackageInfo;
-import org.osgi.framework.Constants;
-import org.osgi.resource.Capability;
-
-public class FelixFrameworkScanner implements FrameworkScanner {
-
-
-    @Override
-    public BundleDescriptor scan(final ArtifactId framework,
-            final File platformFile,
-            final KeyValueMap frameworkProps)
-    throws IOException {
-        final KeyValueMap fwkProps = getFrameworkProperties(frameworkProps, platformFile);
-        if ( fwkProps == null ) {
-            return null;
-        }
-        final Set<PackageInfo> pcks = calculateSystemPackages(fwkProps);
-        final List<Capability> capabilities = calculateSystemCapabilities(fwkProps);
-
-        final BundleDescriptor d = new BundleDescriptor() {
-
-            @Override
-            public String getBundleSymbolicName() {
-                return Constants.SYSTEM_BUNDLE_SYMBOLICNAME;
-            }
-
-            @Override
-            public String getBundleVersion() {
-                return framework.getOSGiVersion().toString();
-            }
-
-            @Override
-            public int getBundleStartLevel() {
-                return 0;
-            }
-
-            @Override
-            public File getArtifactFile() {
-                return platformFile;
-            }
-
-            @Override
-            public Artifact getArtifact() {
-                return new Artifact(framework);
-            }
-
-            @Override
-            public Manifest getManifest() {
-                return new Manifest();
-            }
-        };
-        d.getCapabilities().addAll(capabilities);
-        d.getExportedPackages().addAll(pcks);
-        d.lock();
-        return d;
-    }
-
-    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)
-                .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) {
-        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";
-
-    KeyValueMap getFrameworkProperties(final KeyValueMap appProps, final File framework)
-    throws IOException {
-        final Map<String, Properties> propsMap = new HashMap<>();
-        try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(framework)) ) {
-            boolean done = false;
-            while ( !done ) {
-                final ZipEntry entry = zis.getNextEntry();
-                if ( entry == null ) {
-                    done = true;
-                } else {
-                    final String entryName = entry.getName();
-                    if ( entryName.endsWith(".properties") ) {
-                        final Properties props = new Properties();
-                        props.load(zis);
-
-                        propsMap.put(entryName, props);
-                    }
-                    zis.closeEntry();
-                }
-            }
-        }
-
-        final Properties defaultMap = propsMap.get(DEFAULT_PROPERTIES);
-        if ( defaultMap == null ) {
-            return null;
-        }
-
-        final KeyValueMap frameworkProps = new KeyValueMap();
-        frameworkProps.putAll(appProps);
-
-        // replace variables
-        defaultMap.put("java.specification.version",
-                System.getProperty("java.specification.version", "1.8"));
-
-        StrSubstitutor ss = new StrSubstitutor(new StrLookup() {
-            @Override
-            public String lookup(String key) {
-                // Normally if a variable cannot be found, StrSubstitutor will
-                // leave the raw variable in place. We need to replace it with
-                // nothing in that case.
-
-                String val = defaultMap.getProperty(key);
-                return val != null ? val : "";
-            }
-        });
-        ss.setEnableSubstitutionInVariables(true);
-
-        for(final Object name : defaultMap.keySet()) {
-            if ( frameworkProps.get(name.toString()) == null ) {
-                final String value = (String)defaultMap.get(name);
-                final String substValue = ss.replace(value);
-                frameworkProps.put(name.toString(), substValue);
-            }
-        }
-
-        return frameworkProps;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java
deleted file mode 100644
index 97fa3b7..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/impl/RepoInitScanner.java
+++ /dev/null
@@ -1,65 +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.scanner.impl;
-
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.apache.sling.feature.scanner.spi.ExtensionScanner;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.util.Collections;
-
-public class RepoInitScanner implements ExtensionScanner {
-    private static final Requirement REQUIREMENT_REPOINIT = new RequirementImpl(null, "osgi.implementation",
-            Collections.singletonMap("filter", "(&(osgi.implementation=org.apache.sling.jcr.repoinit)(version>=1.0)(!(version>=2.0)))"),
-                    null);
-
-    @Override
-    public String getId() {
-        return "repoinit";
-    }
-
-    @Override
-    public String getName() {
-        return "Apache Sling Repoinit Scanner";
-    }
-
-    @Override
-    public ContainerDescriptor scan(final Extension extension,
-            final ArtifactManager artifactManager)
-    throws IOException {
-        if (!FeatureConstants.EXTENSION_NAME_REPOINIT.equals(extension.getName()) ) {
-            return null;
-        }
-        if ( extension.getType() != ExtensionType.TEXT ) {
-            return null;
-        }
-
-        final ContainerDescriptor cd = new ContainerDescriptor() {};
-
-        cd.getRequirements().add(REQUIREMENT_REPOINIT);
-
-        cd.lock();
-
-        return cd;
-    }
-}
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java
deleted file mode 100644
index 4c65dc3..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.scanner;
-
-
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java
deleted file mode 100644
index 773f210..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/ExtensionScanner.java
+++ /dev/null
@@ -1,48 +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.scanner.spi;
-
-import java.io.IOException;
-
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.scanner.ContainerDescriptor;
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * The extension scanner scans an extension.
- */
-@ConsumerType
-public interface ExtensionScanner  {
-
-    /** A unique (short) id. */
-    String getId();
-
-    /** A human readable name to identify the scanner. */
-    String getName();
-
-    /**
-     * Try to scan the extension and return a descriptor
-     *
-     * @param extension The extension
-     * @param manager Artifact manager
-     * @return The descriptor or {@code null} if the scanner does not know the extension
-     * @throws IOException If an error occurs while scanning the extension or the extension is invalid
-     */
-    ContainerDescriptor scan(Extension extension,
-            ArtifactManager manager) throws IOException;
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java
deleted file mode 100644
index fcfc0ef..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/FrameworkScanner.java
+++ /dev/null
@@ -1,44 +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.scanner.spi;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.KeyValueMap;
-import org.apache.sling.feature.scanner.BundleDescriptor;
-import org.osgi.annotation.versioning.ConsumerType;
-
-/**
- * The framework scanner scans the framework
- */
-@ConsumerType
-public interface FrameworkScanner  {
-
-    /**
-     * Try to scan the artifact
-     * @param framework The framework artifact id
-     * @param file The framework artifact
-     * @param frameworkProps framework properties to launch the framework
-     * @return A descriptor or {@code null}
-     * @throws IOException If an error occurs while scanning the platform or the artifact is invalid
-     */
-    BundleDescriptor scan(ArtifactId framework,
-            File platformFile,
-            KeyValueMap frameworkProps) throws IOException;
-}
\ No newline at end of file
diff --git a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java b/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java
deleted file mode 100644
index 3ecb9cb..0000000
--- a/featuremodel/feature-analyser/src/main/java/org/apache/sling/feature/scanner/spi/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.scanner.spi;
-
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask
deleted file mode 100644
index dabd8fb..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.analyser.task.AnalyserTask
+++ /dev/null
@@ -1,5 +0,0 @@
-org.apache.sling.feature.analyser.task.impl.CheckBundleExportsImports
-org.apache.sling.feature.analyser.task.impl.CheckBundlesForInitialContent
-org.apache.sling.feature.analyser.task.impl.CheckBundlesForResources
-org.apache.sling.feature.analyser.task.impl.CheckRequirementsCapabilities
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner
deleted file mode 100644
index 643c7cf..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.ExtensionScanner
+++ /dev/null
@@ -1,3 +0,0 @@
-org.apache.sling.feature.scanner.impl.ContentPackagesExtensionScanner
-org.apache.sling.feature.scanner.impl.RepoInitScanner
-
diff --git a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner b/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner
deleted file mode 100644
index ad10c99..0000000
--- a/featuremodel/feature-analyser/src/main/resources/META-INF/services/org.apache.sling.feature.scanner.spi.FrameworkScanner
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.sling.feature.scanner.impl.FelixFrameworkScanner
-
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
deleted file mode 100644
index a8d289c..0000000
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
+++ /dev/null
@@ -1,73 +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.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
deleted file mode 100644
index d5edc80..0000000
--- a/featuremodel/feature-analyser/src/test/java/org/apache/sling/feature/scanner/impl/FelixFrameworkScannerTest.java
+++ /dev/null
@@ -1,70 +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.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
-    public void testGetFrameworkProperties() throws Exception {
-        URL url = getClass().getResource("/test-framework.jar");
-        File fwFile = new File(url.toURI());
-
-        FelixFrameworkScanner ffs = new FelixFrameworkScanner();
-
-        KeyValueMap kvmap = new KeyValueMap();
-        KeyValueMap props = ffs.getFrameworkProperties(kvmap, fwFile);
-        assertEquals("osgi.service; objectClass:List<String>=org.osgi.service.resolver.Resolver; "
-                    + "uses:=org.osgi.service.resolver, "
-                + "osgi.service; objectClass:List<String>=org.osgi.service.startlevel.StartLevel; "
-                    + "uses:=org.osgi.service.startlevel, "
-                + "osgi.service; objectClass:List<String>=org.osgi.service.packageadmin.PackageAdmin; "
-                    + "uses:=org.osgi.service.packageadmin , "
-                + "osgi.ee; osgi.ee=\"OSGi/Minimum\"; version:List<Version>=\"1.0,1.1,1.2\", "
-                + "osgi.ee; osgi.ee=\"JavaSE\"; version:List<Version>=\"1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8\", "
-                + "osgi.ee; osgi.ee=\"JavaSE/compact1\"; version:List<Version>=\"1.8\", "
-                + "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-analyser/src/test/resources/test-framework.jar b/featuremodel/feature-analyser/src/test/resources/test-framework.jar
deleted file mode 100644
index 51fe8a1..0000000
Binary files a/featuremodel/feature-analyser/src/test/resources/test-framework.jar and /dev/null differ
diff --git a/featuremodel/feature-applicationbuilder/pom.xml b/featuremodel/feature-applicationbuilder/pom.xml
deleted file mode 100644
index fed4c08..0000000
--- a/featuremodel/feature-applicationbuilder/pom.xml
+++ /dev/null
@@ -1,167 +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.applicationbuilder</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-
-    <name>Apache Sling Feature Application Builder</name>
-    <description>
-        A feature describes an OSGi system
-    </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-applicationbuilder</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-applicationbuilder</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-applicationbuilder</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                <execution>
-                    <id>unpack-dependencies</id>
-                    <phase>prepare-package</phase>
-                    <goals>
-                        <goal>unpack-dependencies</goal>
-                    </goals>
-                    <configuration>
-                        <excludes>META-INF/**</excludes>
-                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
-                        <overWriteReleases>false</overWriteReleases>
-                        <overWriteSnapshots>true</overWriteSnapshots>
-                        <includeArtifactIds>commons-cli,org.apache.sling.feature,org.apache.sling.feature.support,org.apache.sling.commons.johnzon,slf4j-api,slf4j-simple,osgi.core,org.apache.felix.converter,org.osgi.service.resolver,org.apache.sling.feature.resolver,org.apache.sling.feature.analyser</includeArtifactIds>
-                    </configuration>
-                </execution>
-            </executions>
-            </plugin>
-                <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifest>
-                            <mainClass>org.apache.sling.feature.applicationbuilder.impl.Main</mainClass>
-                        </manifest>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-    
-    <dependencies>
-        <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.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-             <groupId>commons-cli</groupId>
-             <artifactId>commons-cli</artifactId>
-             <version>1.3.1</version>
-        </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.analyser</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.sling</groupId>
-            <artifactId>org.apache.sling.feature.resolver</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>
-        </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.framework</artifactId>
-            <version>5.6.10</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.osgi</groupId>
-            <artifactId>org.osgi.service.resolver</artifactId>
-            <version>1.0.1</version>
-            <scope>provided</scope>
-        </dependency>
-                
-        <!-- Testing -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java b/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
deleted file mode 100644
index d07be10..0000000
--- a/featuremodel/feature-applicationbuilder/src/main/java/org/apache/sling/feature/applicationbuilder/impl/Main.java
+++ /dev/null
@@ -1,203 +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.applicationbuilder.impl;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.IOUtils;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.stream.Stream;
-
-public class Main {
-
-    private static Logger LOGGER;
-
-    private static String output;
-
-    private static String filesInput;
-
-    private static String dirsInput;
-
-    private static String repoUrls;
-
-    private static String propsFile;
-
-    /**
-     * Parse the command line parameters and update a configuration object.
-     * @param args Command line parameters
-     * @return Configuration object.
-     */
-    private static void parseArgs(final String[] args) {
-        final Option repoOption =  Option.builder("u").hasArg().argName("Set repository url")
-                .desc("repository url").build();
-
-        final Option filesOption =  new Option("f", true, "Set feature files (comma separated)");
-        final Option dirsOption = new Option("d", true, "Set feature file dirs (comma separated)");
-        final Option propsOption =  new Option("p", true, "sling.properties file");
-
-
-        final Option outputOption = Option.builder("o").hasArg().argName("Set output file")
-                .desc("output file").build();
-
-        final Options options = new Options();
-        options.addOption(repoOption);
-        options.addOption(filesOption);
-        options.addOption(dirsOption);
-        options.addOption(outputOption);
-        options.addOption(propsOption);
-
-        final CommandLineParser parser = new DefaultParser();
-        try {
-            final CommandLine cl = parser.parse(options, args);
-
-            if ( cl.hasOption(repoOption.getOpt()) ) {
-                repoUrls = cl.getOptionValue(repoOption.getOpt());
-            }
-            if ( cl.hasOption(filesOption.getOpt()) ) {
-                filesInput = cl.getOptionValue(filesOption.getOpt());
-            }
-            if ( cl.hasOption(dirsOption.getOpt()) ) {
-                dirsInput = cl.getOptionValue(dirsOption.getOpt());
-            }
-            if ( cl.hasOption(outputOption.getOpt()) ) {
-                output = cl.getOptionValue(outputOption.getOpt());
-            }
-            if ( cl.hasOption(propsOption.getOpt()) ) {
-                propsFile = cl.getOptionValue(propsOption.getOpt());
-            }
-        } catch ( final ParseException pe) {
-            LOGGER.error("Unable to parse command line: {}", pe.getMessage(), pe);
-            System.exit(1);
-        }
-        if ( filesInput == null && dirsInput == null) {
-            LOGGER.error("Required argument missing: model files or directory");
-            System.exit(1);
-        }
-    }
-
-    private static ArtifactManager getArtifactManager() {
-        final ArtifactManagerConfig amConfig = new ArtifactManagerConfig();
-        if ( repoUrls != null ) {
-            amConfig.setRepositoryUrls(repoUrls.split(","));
-        }
-        try {
-            return ArtifactManager.getArtifactManager(amConfig);
-        } catch ( IOException ioe) {
-            LOGGER.error("Unable to create artifact manager " + ioe.getMessage(), ioe);
-            System.exit(1);
-        }
-        // we never reach this, but have to keep the compiler happy
-        return null;
-    }
-
-    private static FeatureResolver getFeatureResolver(ArtifactManager am) {
-        return new FrameworkResolver(am, Collections.emptyMap());
-    }
-
-    public static void main(final String[] args) {
-        // setup logging
-        System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
-        System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
-        System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
-        System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
-
-        LOGGER = LoggerFactory.getLogger("applicationbuilder");
-
-        LOGGER.info("Apache Sling Feature Application Builder");
-        LOGGER.info("");
-
-        parseArgs(args);
-
-        final ArtifactManager am = getArtifactManager();
-
-
-        final String[] files =
-                Stream.concat(
-                    Stream.of(filesInput != null ? filesInput.split(",") : new String[0])
-                        .map(path -> new File(path))
-                        .filter(File::isFile),
-                    Stream.of(dirsInput != null ? dirsInput.split(",") : new String[0])
-                        .map(path -> new File(path))
-                        .filter(File::isDirectory)
-                        .flatMap(dir ->
-                            Stream.of(dir.listFiles())))
-                .filter(file -> !file.getName().startsWith("."))
-                .sorted()
-                .map(File::getAbsolutePath)
-                .toArray(String[]::new);
-
-        if (files.length == 0) {
-            LOGGER.error("No feature files found.");
-            System.exit(1);
-        }
-
-        try (FeatureResolver fr = getFeatureResolver(am)) {
-            writeApplication(buildApplication(ApplicationResolverAssembler.assembleApplication(null, am, fr, files)), output == null ? "application.json" : output);
-
-        } catch ( final IOException ioe) {
-            LOGGER.error("Unable to read feature/application files " + ioe.getMessage(), ioe);
-            System.exit(1);
-        } catch ( final Exception e) {
-            LOGGER.error("Problem generating application", e);
-            System.exit(1);
-        }
-    }
-
-    private static Application buildApplication(final Application app) {
-        final org.apache.sling.feature.Artifact a = new org.apache.sling.feature.Artifact(ArtifactId.parse("org.apache.sling/org.apache.sling.launchpad.api/1.2.0"));
-        a.getMetadata().put(org.apache.sling.feature.Artifact.KEY_START_ORDER, "1");
-        app.getBundles().add(a);
-        // sling.properties (TODO)
-        if ( propsFile == null ) {
-            app.getFrameworkProperties().put("org.osgi.framework.bootdelegation", "sun.*,com.sun.*");
-        } else {
-
-        }
-        // felix framework hard coded for now
-        app.setFramework(IOUtils.getFelixFrameworkId(null));
-        return app;
-    }
-
-    private static void writeApplication(final Application app, final String out) {
-        LOGGER.info("Writing application: " + out);
-        final File file = new File(out);
-        try ( final FileWriter writer = new FileWriter(file)) {
-            ApplicationJSONWriter.write(writer, app);
-        } catch ( final IOException ioe) {
-            LOGGER.error("Unable to write application to {} : {}", out, ioe.getMessage(), ioe);
-            System.exit(1);
-        }
-    }
-}
diff --git a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java b/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
deleted file mode 100644
index c80f485..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/java/org/apache/sling/feature/applicationbuilder/impl/ApplicationBuilderTest.java
+++ /dev/null
@@ -1,177 +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.applicationbuilder.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonStructure;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.builder.ApplicationBuilder;
-import org.apache.sling.feature.builder.BuilderContext;
-import org.apache.sling.feature.builder.FeatureProvider;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.Constants;
-
-public class ApplicationBuilderTest {
-    private Path tempDir;
-
-    @Before
-    public void setup() throws Exception {
-        tempDir = Files.createTempDirectory(getClass().getSimpleName());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // Delete the temp dir again
-        Files.walk(tempDir)
-            .sorted(Comparator.reverseOrder())
-            .map(Path::toFile)
-            .forEach(File::delete);
-    }
-
-    private Map<String, String> getFrameworkProps() {
-        return Collections.singletonMap(Constants.FRAMEWORK_STORAGE, tempDir.toFile().getAbsolutePath());
-    }
-
-    @Test
-    public void testBundleOrdering() throws Exception {
-        FeatureProvider fp = new TestFeatureProvider();
-        BuilderContext bc = new BuilderContext(fp);
-        ArtifactManager am = ArtifactManager.getArtifactManager(new ArtifactManagerConfig());
-
-        Feature fa = readFeature("/featureA.json", am);
-        Feature fb = readFeature("/featureB.json", am);
-        Feature[] features = {fa, fb};
-
-        try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
-            Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
-            String actualJSON = writeApplication(app);
-
-            String expectedJSON = "{\"features\":["
-                    + "\"org.apache.sling.test.features:featureB:1.0.0\","
-                    + "\"org.apache.sling.test.features:featureA:1.0.0\"],"
-                + "\"bundles\":["
-                    + "{\"id\":\"commons-io:commons-io:2.6\",\"start-level\":\"10\",\"start-order\":\"10\"},"
-                    + "{\"id\":\"org.apache.felix:org.apache.felix.http.servlet-api:1.1.2\",\"start-level\":\"15\",\"start-order\":\"15\"},"
-                    + "{\"id\":\"commons-fileupload:commons-fileupload:1.3.3\",\"start-level\":\"16\",\"start-order\":\"16\"}]}";
-
-            StringWriter expectedWriter = new StringWriter();
-            StringWriter actualWriter = new StringWriter();
-
-            canonicalize(expectedJSON, expectedWriter, actualJSON, actualWriter);
-            assertEquals(expectedWriter.toString(), actualWriter.toString());
-        }
-    }
-
-    @Test
-    public void testFeatureDependency() throws Exception {
-        FeatureProvider fp = new TestFeatureProvider();
-        BuilderContext bc = new BuilderContext(fp);
-        ArtifactManager am = ArtifactManager.getArtifactManager(new ArtifactManagerConfig());
-
-        // Feature D has a bundle (slf4j-api) with a dependency on feature C,
-        // which provides a package for slf4j
-        Feature fc = readFeature("/featureC.json", am);
-        Feature fd = readFeature("/featureD.json", am);
-        Feature[] features = {fd, fc};
-
-        try (FeatureResolver fr = new FrameworkResolver(am, getFrameworkProps())) {
-            Application app = ApplicationBuilder.assemble(null, bc, ApplicationResolverAssembler.sortFeatures(fr, features));
-            String genApp = writeApplication(app);
-
-            String expected = "{\"features\":["
-                    + "\"org.apache.sling.test.features:featureC:1.0.0\","
-                    + "\"org.apache.sling.test.features:featureD:1.0.0\"],"
-                    + "\"bundles\":[{\"id\":\"org.slf4j:slf4j-api:1.7.25\",\"start-level\":\"6\",\"start-order\":\"6\"}]}";
-
-            StringWriter expectedWriter = new StringWriter();
-            StringWriter actualWriter = new StringWriter();
-            canonicalize(expected, expectedWriter, genApp, actualWriter);
-
-            assertEquals(expectedWriter.toString(), actualWriter.toString());
-        }
-    }
-
-    // Turn JSON into pretty-formatted canoncical JSON that should be comparable using String compare
-    private void canonicalize(String expected, StringWriter expectedWriter, String actual, StringWriter actualWriter) {
-        JsonStructure es = Json.createReader(new StringReader(expected)).read();
-        JsonStructure ea = Json.createReader(new StringReader(actual)).read();
-
-        JsonWriterFactory writerFactory = Json.createWriterFactory(
-                Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
-        JsonWriter w = writerFactory.createWriter(expectedWriter);
-        w.write(es);
-
-        JsonWriter w2 = writerFactory.createWriter(actualWriter);
-        w2.write(ea);
-    }
-
-    private Feature readFeature(final String res,
-            final ArtifactManager artifactManager) throws Exception {
-        URL url = getClass().getResource(res);
-        String file = new File(url.toURI()).getAbsolutePath();
-        final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(file);
-
-        try (final FileReader r = new FileReader(featureArtifact.getFile())) {
-            final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), SubstituteVariables.RESOLVE);
-            return f;
-        }
-    }
-
-    private static String writeApplication(Application app) throws Exception {
-        Writer writer = new StringWriter();
-        ApplicationJSONWriter.write(writer, app);
-        return writer.toString();
-    }
-
-    private static class TestFeatureProvider implements FeatureProvider {
-        @Override
-        public Feature provide(ArtifactId id) {
-            return null;
-        }
-    }
-}
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json
deleted file mode 100644
index 1daed33..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureA.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "id": "org.apache.sling.test.features/featureA/1.0.0",
-    "bundles": 
-        ["commons-fileupload/commons-fileupload/1.3.3"]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json
deleted file mode 100644
index 952c810..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureB.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "id": "org.apache.sling.test.features/featureB/1.0.0",
-    "bundles": 
-        [
-            {
-                "id": "org.apache.felix/org.apache.felix.http.servlet-api/1.1.2",
-                "start-order" : 10
-            },
-            {
-                "id": "commons-io/commons-io/2.6",
-                "start-order" : 5
-            }
-        ]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json
deleted file mode 100644
index 0aed875..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureC.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "id": "org.apache.sling.test.features/featureC/1.0.0",
-    "capabilities": [
-        {
-            "namespace": "org.foo.bar",
-            "attributes": {
-                "org.foo.bar": "toast",
-                "version:Version": "1.1"
-            }
-        }, {
-            "namespace": "osgi.wiring.package",
-            "attributes": {
-                "osgi.wiring.package": "org.slf4j.impl",
-                "version:Version": "1.7.1.test"
-            }
-        }
-    ]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json b/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json
deleted file mode 100644
index e9aa806..0000000
--- a/featuremodel/feature-applicationbuilder/src/test/resources/featureD.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "id": "org.apache.sling.test.features/featureD/1.0.0",
-    "bundles": 
-        ["org.slf4j/slf4j-api/1.7.25"]
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/pom.xml b/featuremodel/feature-io/pom.xml
deleted file mode 100644
index 8053a89..0000000
--- a/featuremodel/feature-io/pom.xml
+++ /dev/null
@@ -1,120 +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.io</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <packaging>bundle</packaging>
-    
-    <name>Apache Sling Feature IO Module</name>
-    <description>
-        IO functionality for the Feature Model
-    </description>
-
-    <properties>
-        <sling.java.version>8</sling.java.version>
-    </properties>
-
-    <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.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>
-        <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.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>
-
-        <!-- 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-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java
deleted file mode 100644
index 45f27be..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactHandler.java
+++ /dev/null
@@ -1,42 +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.io;
-
-import java.io.File;
-
-/**
- * A handler provides a file object for an artifact.
- */
-public class ArtifactHandler {
-
-    private final String url;
-
-    private final File file;
-
-    public ArtifactHandler(final String url, final File file) {
-        this.url = url;
-        this.file = file;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public File getFile() {
-        return file;
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
deleted file mode 100644
index 954ac1a..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
+++ /dev/null
@@ -1,366 +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.io;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.file.Files;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-/**
- * The artifact manager is the central service to get artifacts.
- * It uses {@link ArtifactProvider}s to get artifacts. The
- * providers are loaded using the service loader.
- */
-public class ArtifactManager {
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    /** The map of providers. */
-    private final Map<String, ArtifactProvider> providers;
-
-    /** The configuration */
-    private final ArtifactManagerConfig config;
-
-    /**
-     * Get an artifact manager based on the configuration
-     * @param config The configuration
-     * @return The artifact manager
-     * @throws IOException If the manager can't be initialized
-     */
-    public static ArtifactManager getArtifactManager(final ArtifactManagerConfig config) throws IOException {
-        final ServiceLoader<ArtifactProvider> loader = ServiceLoader.load(ArtifactProvider.class);
-        final Map<String, ArtifactProvider> providers = new HashMap<>();
-        for(final ArtifactProvider provider : loader) {
-            providers.put(provider.getProtocol(), provider);
-        }
-
-        final String[] repositoryURLs = new String[config.getRepositoryUrls().length];
-        int index = 0;
-        for(final String urlString : config.getRepositoryUrls()) {
-            repositoryURLs[index] = urlString;
-            index++;
-        }
-        // default
-        if ( !providers.containsKey("*") ) {
-            providers.put("*", new DefaultArtifactHandler());
-        }
-
-        return new ArtifactManager(config, providers);
-    }
-
-    ArtifactManager(final ArtifactManagerConfig config, final Map<String, ArtifactProvider> providers)
-    throws IOException {
-        this.config = config;
-        this.providers = providers;
-        try {
-            for(final ArtifactProvider provider : this.providers.values()) {
-                provider.init(config);
-            }
-        } catch ( final IOException io) {
-            shutdown();
-            throw io;
-        }
-    }
-
-    /**
-     * Shutdown the artifact manager.
-     */
-    public void shutdown() {
-        for(final ArtifactProvider provider : this.providers.values()) {
-            provider.shutdown();
-        }
-        this.providers.clear();
-    }
-
-    private final File getArtifactFromProviders(final String url, final String relativeCachePath) throws IOException {
-        final int pos = url.indexOf(":");
-        final String scheme = url.substring(0, pos);
-
-        ArtifactProvider provider = this.providers.get(scheme);
-        if ( provider == null ) {
-            provider = this.providers.get("*");
-        }
-        if ( provider == null ) {
-            throw new IOException("No URL provider found for " + url);
-        }
-        return provider.getArtifact(url, relativeCachePath);
-    }
-
-    /**
-     * Get the full artifact url and file for an artifact.
-     * @param url Artifact url or relative path.
-     * @return Absolute url and file in the form of a handler.
-     * @throws IOException If something goes wrong.
-     */
-    public ArtifactHandler getArtifactHandler(final String url) throws IOException {
-        logger.debug("Trying to get artifact for {}", url);
-
-        final String path;
-
-        if ( url.startsWith("mvn:") ) {
-            // mvn url
-            path = ArtifactId.fromMvnUrl(url).toMvnPath();
-
-        } else if ( url.startsWith(":") ) {
-            // repository path
-            path = url.substring(1);
-
-        } else if ( url.indexOf(":/") > 0 ) {
-
-            // absolute URL
-            int pos = url.indexOf(":/") + 2;
-            while ( url.charAt(pos) == '/') {
-                pos++;
-            }
-            final File file = this.getArtifactFromProviders(url, url.substring(pos));
-            if ( file == null || !file.exists()) {
-                throw new IOException("Artifact " + url + " not found.");
-            }
-            return new ArtifactHandler(url, file);
-
-        } else {
-            // file (either relative or absolute)
-            final File f = new File(url);
-            if ( !f.exists()) {
-                throw new IOException("Artifact " + url + " not found.");
-            }
-            return new ArtifactHandler(f.toURI().toString(), f);
-        }
-        logger.debug("Querying repositories for {}", path);
-
-        for(final String repoUrl : this.config.getRepositoryUrls()) {
-            final StringBuilder builder = new StringBuilder();
-            builder.append(repoUrl);
-            builder.append('/');
-            builder.append(path);
-
-            final String artifactUrl = builder.toString();
-            final int pos = artifactUrl.indexOf(":");
-            final String scheme = artifactUrl.substring(0, pos);
-
-            ArtifactProvider handler = this.providers.get(scheme);
-            if ( handler == null ) {
-                handler = this.providers.get("*");
-            }
-            if ( handler == null ) {
-                throw new IOException("No URL handler found for " + artifactUrl);
-            }
-
-            logger.debug("Checking {} to get artifact from {}", handler, artifactUrl);
-
-            final File file = handler.getArtifact(artifactUrl, path);
-            if ( file != null ) {
-                logger.debug("Found artifact {}", artifactUrl);
-                return new ArtifactHandler(artifactUrl, file);
-            }
-
-            // check for SNAPSHOT
-            final int lastSlash = artifactUrl.lastIndexOf('/');
-            final int startSnapshot = artifactUrl.indexOf("-SNAPSHOT", lastSlash + 1);
-
-            if ( startSnapshot > -1 ) {
-                // special snapshot handling
-                final String metadataUrl = artifactUrl.substring(0, lastSlash) + "/maven-metadata.xml";
-                try {
-                    final ArtifactHandler metadataHandler = this.getArtifactHandler(metadataUrl);
-
-                    final String contents = getFileContents(metadataHandler);
-
-                    final String latestVersion = getLatestSnapshot(contents);
-                    if ( latestVersion != null ) {
-                        final String name = artifactUrl.substring(lastSlash); // includes slash
-                        final String fullURL = artifactUrl.substring(0, lastSlash) + name.replace("SNAPSHOT", latestVersion);
-                        int pos2 = fullURL.indexOf(":/") + 2;
-                        while ( fullURL.charAt(pos2) == '/') {
-                            pos2++;
-                        }
-                        final File file2 = this.getArtifactFromProviders(fullURL, path);
-                        if ( file2 == null || !file2.exists()) {
-                            throw new IOException("Artifact " + fullURL + " not found.");
-                        }
-                        return new ArtifactHandler(artifactUrl, file2);
-                    }
-                } catch ( final IOException ignore ) {
-                    // we ignore this but report the original 404
-                }
-            }
-        }
-
-        throw new IOException("Artifact " + url + " not found in any repository.");
-    }
-
-    protected String getFileContents(final ArtifactHandler handler) throws IOException {
-        final StringBuilder sb = new StringBuilder();
-        for(final String line : Files.readAllLines(handler.getFile().toPath())) {
-            sb.append(line).append('\n');
-        }
-
-        return sb.toString();
-    }
-
-    public static String getValue(final String xml, final String[] xpath) {
-        String value = null;
-        int pos = 0;
-        for(final String name : xpath) {
-            final String element = '<' + name + '>';
-
-            pos = xml.indexOf(element, pos);
-            if ( pos == -1 ) {
-                final String elementWithAttributes = '<' + name + ' ';
-                pos = xml.indexOf(elementWithAttributes, pos);
-                if ( pos == -1 ) {
-                    break;
-                }
-            }
-            pos = xml.indexOf('>', pos) + 1;
-        }
-        if ( pos != -1 ) {
-            final int endPos = xml.indexOf("</", pos);
-            if ( endPos != -1 ) {
-                value = xml.substring(pos, endPos).trim();
-            }
-        }
-        return value;
-    }
-    public static String getLatestSnapshot(final String mavenMetadata) {
-        final String timestamp = getValue(mavenMetadata, new String[] {"metadata", "versioning", "snapshot", "timestamp"});
-        final String buildNumber = getValue(mavenMetadata, new String[] {"metadata", "versioning", "snapshot", "buildNumber"});
-
-        if ( timestamp != null && buildNumber != null ) {
-            return timestamp + '-' + buildNumber;
-        }
-
-        return null;
-    }
-
-    private static final class DefaultArtifactHandler implements ArtifactProvider {
-
-        private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-        private volatile File cacheDir;
-
-        private volatile ArtifactProviderContext config;
-
-        @Override
-        public String getProtocol() {
-            return "*";
-        }
-
-        @Override
-        public void init(final ArtifactProviderContext config) throws IOException {
-            this.cacheDir = config.getCacheDirectory();
-            this.config = config;
-        }
-
-        @Override
-        public void shutdown() {
-            this.config = null;
-            this.cacheDir = null;
-        }
-
-        @Override
-        public File getArtifact(final String url, final String relativeCachePath) {
-            logger.debug("Checking url to be local file {}", url);
-            // check if this is already a local file
-            try {
-                final File f = new File(new URL(url).toURI());
-                if ( f.exists() ) {
-                    this.config.incLocalArtifacts();
-                    return f;
-                }
-                return null;
-            } catch ( final URISyntaxException ise) {
-                // ignore
-            } catch ( final IllegalArgumentException iae) {
-                // ignore
-            } catch ( final MalformedURLException mue) {
-                // ignore
-            }
-            logger.debug("Checking remote url {}", url);
-            try {
-                // check for url
-                if ( url.indexOf(":") == -1 ) {
-                    return null;
-                }
-
-                final String filePath = (this.cacheDir.getAbsolutePath() + File.separatorChar + relativeCachePath).replace('/', File.separatorChar);
-                final File cacheFile = new File(filePath);
-
-                if ( !cacheFile.exists() ) {
-                    cacheFile.getParentFile().mkdirs();
-                    final URL u = new URL(url);
-                    final URLConnection con = u.openConnection();
-                    con.connect();
-
-                    final InputStream readIS = con.getInputStream();
-                    final byte[] buffer = new byte[32768];
-                    int l;
-                    OutputStream os = null;
-                    try {
-                        os = new FileOutputStream(cacheFile);
-                        while ( (l = readIS.read(buffer)) >= 0 ) {
-                            os.write(buffer, 0, l);
-                        }
-                    } finally {
-                        try {
-                            readIS.close();
-                        } catch ( final IOException ignore) {
-                            // ignore
-                        }
-                        if ( os != null ) {
-                            try {
-                                os.close();
-                            } catch ( final IOException ignore ) {
-                                // ignore
-
-                            }
-                        }
-                    }
-                    this.config.incDownloadedArtifacts();
-                } else {
-                    this.config.incCachedArtifacts();
-                }
-                return cacheFile;
-            } catch ( final Exception e) {
-                logger.info("Artifact not found in one repository", e);
-                // ignore for now
-                return null;
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "DefaultArtifactHandler";
-        }
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
deleted file mode 100644
index 5df9ed8..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
+++ /dev/null
@@ -1,142 +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.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-
-/**
- * This class holds the configuration of artifact manager.
- */
-public class ArtifactManagerConfig implements ArtifactProviderContext {
-
-    /** The repository urls. */
-    private volatile String[] repositoryUrls;
-
-    /** The cache directory. */
-    private volatile File cacheDirectory;
-
-    private volatile long cachedArtifacts;
-
-    private volatile long downloadedArtifacts;
-
-    private volatile long localArtifacts;
-
-    /**
-     * Create a new configuration object.
-     * Set the default values
-     */
-    public ArtifactManagerConfig() {
-        // set defaults
-        this.repositoryUrls = new String[] {
-                "file://" + System.getProperty("user.home") + "/.m2/repository",
-                "https://repo.maven.apache.org/maven2",
-                "https://repository.apache.org/content/groups/snapshots"
-                };
-        try {
-            this.cacheDirectory = Files.createTempDirectory("slingfeature").toFile();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Set the repository urls
-     * @param urls The repository urls
-     */
-    public void setRepositoryUrls(final String[] urls) {
-        if ( urls == null || urls.length == 0 ) {
-            this.repositoryUrls = null;
-        } else {
-            this.repositoryUrls = new String[urls.length];
-            System.arraycopy(urls, 0, this.repositoryUrls, 0, urls.length);
-            for(int i=0; i<this.repositoryUrls.length; i++) {
-                if ( this.repositoryUrls[i].endsWith("/") ) {
-                    this.repositoryUrls[i] = this.repositoryUrls[i].substring(0, this.repositoryUrls[i].length() - 1);
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the repository urls.
-     * A repository url does not end with a slash.
-     * @return The repository urls.
-     */
-    public String[] getRepositoryUrls() {
-        return repositoryUrls;
-    }
-
-    /**
-     * Get the cache directory
-     * @return The cache directory.
-     */
-    @Override
-    public File getCacheDirectory() {
-        return cacheDirectory;
-    }
-
-    /**
-     * Set the cache directory
-     * @param dir The cache directory
-     */
-    public void setCacheDirectory(final File dir) {
-        this.cacheDirectory = dir;
-    }
-
-    @Override
-    public void incCachedArtifacts() {
-        this.cachedArtifacts++;
-    }
-
-    @Override
-    public void incDownloadedArtifacts() {
-        this.downloadedArtifacts++;
-    }
-
-    @Override
-    public void incLocalArtifacts() {
-        this.localArtifacts++;
-    }
-
-    /**
-     * Get the number of cached artifacts
-     * @return The number of cached artifacts
-     */
-    public long getCachedArtifacts() {
-        return this.cachedArtifacts;
-    }
-
-    /**
-     * Get the number of downloaded artifacts
-     * @return The number of downloaded artifacts
-     */
-    public long getDownloadedArtifacts() {
-        return this.downloadedArtifacts;
-    }
-
-    /**
-     * Get the number of local artifacts
-     * @return The number of local artifacts
-     */
-    public long getLocalArtifacts() {
-        return this.localArtifacts;
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
deleted file mode 100644
index 70af38c..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/IOUtils.java
+++ /dev/null
@@ -1,243 +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.io;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-public class IOUtils {
-
-    /** The extension for a reference file. */
-    public static final String EXTENSION_REF_FILE = ".ref";
-
-    /** The extension for a feature file. */
-    public static final String EXTENSION_FEATURE_FILE = ".json";
-
-    /** The default directory to search for features. */
-    public static final String DEFAULT_DIRECTORY = "features";
-
-    /** The default name of the feature file. */
-    public static final String DEFAULT_FEATURE_FILE = "feature" + EXTENSION_FEATURE_FILE;
-
-    /**
-     * Parse a feature reference file
-     * @param file The file
-     * @return The referenced features
-     * @throws IOException If reading fails
-     */
-    public static List<String> parseFeatureRefFile(final File file)
-    throws IOException {
-        final List<String> result = new ArrayList<>();
-        final List<String> lines = Files.readAllLines(file.toPath());
-        for(String line : lines) {
-            line = line.trim();
-            if ( !line.isEmpty() && !line.startsWith("#") ) {
-                if ( line.indexOf(':') == -1 ) {
-                    result.add(new File(line).getAbsolutePath());
-                } else {
-                    result.add(line);
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Get the list of feature files.
-     * If the provided list of files is {@code null} or an empty array, the default is used.
-     * The default checks for the following places, the first one found is used. If none is
-     * found an empty list is returned.
-     * <ol>
-     *   <li>A directory named {@link #DEFAULT_DIRECTORY} in the current directory
-     *   <li>A file named {@link #DEFAULT_FEATURE_FILE} in the current directory
-     *   <li>A directory named {@link #DEFAULT_DIRECTORY} in the home directory
-     *   <li>A file named {@link #DEFAULT_FEATURE_FILE} in the home directory
-     * </ol>
-     *
-     * The list of files is processed one after the other. If it is relative, it is
-     * first tried to be resolved against the current directory and then against the
-     * home directory.
-     * If an entry denotes a directory, all children ending in {@link #EXTENSION_FEATURE_FILE} or
-     * {@link #EXTENSION_REF_FILE} of that directory are read.
-     * If a file ends in {@link #EXTENSION_REF_FILE} the contents is read and every line not
-     * starting with the hash sign is considered a reference to a feature artifact.
-     *
-     * @param homeDirectory If relative files should be resolved, this is the directory to use
-     * @param files Optional list of files. If none is provided, a default is used.
-     * @return The list of files.
-     * @throws IOException If an error occurs.
-     */
-    public static List<String> getFeatureFiles(final File homeDirectory, final String... files)
-    throws IOException {
-        String[] featureFiles = files;
-        if ( featureFiles == null || featureFiles.length == 0 ) {
-            // Default value - check feature directory otherwise features file
-            final File[] candidates = new File[] {
-                    new File(homeDirectory, DEFAULT_DIRECTORY),
-                    new File(homeDirectory, DEFAULT_FEATURE_FILE),
-                    new File(DEFAULT_DIRECTORY),
-                    new File(DEFAULT_FEATURE_FILE)
-            };
-            File f = null;
-            for(final File c : candidates) {
-                if ( c.exists() ) {
-                    f = c;
-                    break;
-                }
-            }
-            // nothing found, we default to the first candidate and fail later
-            if ( f == null ) {
-                f = candidates[0];
-            }
-
-            featureFiles = new String[] {f.getAbsolutePath()};
-        }
-
-        final List<String> paths = new ArrayList<>();
-        for(final String name : featureFiles) {
-            // check for absolute
-            if ( name.indexOf(':') > 1 ) {
-                paths.add(name);
-            } else {
-                // file or relative
-                File f = null;
-                final File test = new File(name);
-                if ( test.isAbsolute() ) {
-                    f = test;
-                } else {
-                    final File[] candidates = {
-                            new File(homeDirectory, name),
-                            new File(homeDirectory, DEFAULT_DIRECTORY + File.separatorChar + name),
-                            new File(name),
-                            new File(DEFAULT_DIRECTORY + File.separatorChar + name),
-                    };
-                    for(final File c : candidates) {
-                        if ( c.exists() && c.isFile() ) {
-                            f = c;
-                            break;
-                        }
-                    }
-                }
-
-                if ( f != null && f.exists() ) {
-                    if ( f.isFile() ) {
-                        processFile(paths, f);
-                    } else {
-                        processDir(paths, f);
-                    }
-                } else {
-                    // we simply add the path and fail later on
-                    paths.add(new File(name).getAbsolutePath());
-                }
-            }
-        }
-
-        Collections.sort(paths, FEATURE_PATH_COMP);
-        return paths;
-    }
-
-    /**
-     * Read the feature
-     *
-     * @param url The feature url
-     * @param artifactManager The artifact manager to read the feature
-     * @param substituteVariables Variable substitution handling
-     * @return The read feature
-     * @throws IOException If reading fails
-     */
-    public static Feature getFeature(final String url,
-            final ArtifactManager artifactManager,
-            final SubstituteVariables substituteVariables)
-    throws IOException {
-        final ArtifactHandler featureArtifact = artifactManager.getArtifactHandler(url);
-
-        try (final FileReader r = new FileReader(featureArtifact.getFile())) {
-            final Feature f = FeatureJSONReader.read(r, featureArtifact.getUrl(), substituteVariables);
-            return f;
-        }
-    }
-
-    /**
-     * Get an artifact id for the Apache Felix framework
-     * @param version The version to use or {@code null} for the default version
-     * @return The artifact id
-     * @throws IllegalArgumentException If the provided version is invalid
-     */
-    public static ArtifactId getFelixFrameworkId(final String version) {
-        return new ArtifactId("org.apache.felix",
-                "org.apache.felix.framework",
-                version != null ? version : "5.6.10", null, null);
-    }
-
-    static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
-        @Override
-        public int compare(final String o1, final String o2) {
-            // windows path conversion
-            final String key1 = o1.replace(File.separatorChar, '/');
-            final String key2 = o2.replace(File.separatorChar, '/');
-
-            final int lastSlash1 = key1.lastIndexOf('/');
-            final int lastSlash2 = key2.lastIndexOf('/');
-            if ( lastSlash1 == -1 || lastSlash2 == -1 ) {
-                return o1.compareTo(o2);
-            }
-            final String path1 = key1.substring(0, lastSlash1 + 1);
-            final String path2 = key2.substring(0, lastSlash2 + 1);
-            if ( path1.equals(path2) ) {
-                return o1.compareTo(o2);
-            }
-            if ( path1.startsWith(path2) ) {
-                return 1;
-            } else if ( path2.startsWith(path1) ) {
-                return -1;
-            }
-            return o1.compareTo(o2);
-        }
-    };
-
-    private static void processDir(final List<String> paths, final File dir)
-    throws IOException {
-        for(final File f : dir.listFiles()) {
-            if ( f.isFile() && !f.getName().startsWith(".")) {
-                // check if file is a reference
-                if ( f.getName().endsWith(EXTENSION_REF_FILE) || f.getName().endsWith(EXTENSION_FEATURE_FILE) ) {
-                    processFile(paths, f);
-                }
-            }
-        }
-    }
-
-    private static void processFile(final List<String> paths, final File f)
-    throws IOException {
-        if ( f.getName().endsWith(EXTENSION_REF_FILE) ) {
-            paths.addAll(parseFeatureRefFile(f));
-        } else {
-            paths.add(f.getAbsolutePath());
-        }
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java
deleted file mode 100644
index 88d3bc5..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONReader.java
+++ /dev/null
@@ -1,92 +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.io.json;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-
-/**
- * This class offers a method to read an {@code Application} using a {@code Reader} instance.
- */
-public class ApplicationJSONReader extends JSONReaderBase {
-
-    /**
-     * Read a new application from the reader
-     * The reader is not closed. It is up to the caller to close the reader.
-     *
-     * @param reader The reader for the feature
-     * @return The application
-     * @throws IOException If an IO errors occurs or the JSON is invalid.
-     */
-    public static Application read(final Reader reader)
-    throws IOException {
-        try {
-            final ApplicationJSONReader mr = new ApplicationJSONReader();
-            mr.readApplication(reader);
-            return mr.app;
-        } catch (final IllegalStateException | IllegalArgumentException e) {
-            throw new IOException(e);
-        }
-    }
-
-    /** The read application. */
-    private final Application app;
-
-    /**
-     * Private constructor
-     */
-    private ApplicationJSONReader() {
-        super(null);
-        this.app = new Application();
-    }
-
-    /**
-     * Read a full application
-     * @param reader The reader
-     * @throws IOException If an IO error occurs or the JSON is not valid.
-     */
-    private void readApplication(final Reader reader)
-    throws IOException {
-        final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-
-        @SuppressWarnings("unchecked")
-        final Map<String, Object> map = (Map<String, Object>) JSONUtil.getValue(json);
-
-        final String frameworkId = this.getProperty(map, JSONConstants.APP_FRAMEWORK);
-        if ( frameworkId != null ) {
-            app.setFramework(ArtifactId.parse(frameworkId));
-        }
-        this.readBundles(map, app.getBundles(), app.getConfigurations());
-        this.readFrameworkProperties(map, app.getFrameworkProperties());
-        this.readConfigurations(map, app.getConfigurations());
-
-        this.readExtensions(map,
-                JSONConstants.APP_KNOWN_PROPERTIES,
-                this.app.getExtensions(), this.app.getConfigurations());
-    }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java
deleted file mode 100644
index bdf4902..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ApplicationJSONWriter.java
+++ /dev/null
@@ -1,97 +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.io.json;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-/**
- * Simple JSON writer for an application
- */
-public class ApplicationJSONWriter extends JSONWriterBase {
-
-    /**
-     * Writes the application to the writer.
-     * The writer is not closed.
-     * @param writer Writer
-     * @param app The application
-     * @throws IOException If writing fails
-     */
-    public static void write(final Writer writer, final Application app)
-    throws IOException {
-        final ApplicationJSONWriter w = new ApplicationJSONWriter();
-        w.writeApp(writer, app);
-    }
-
-   private void writeApp(final Writer writer, final Application app)
-    throws IOException {
-       JsonObjectBuilder ob = Json.createObjectBuilder();
-
-        // framework
-        if ( app.getFramework() != null ) {
-            ob.add(JSONConstants.APP_FRAMEWORK, app.getFramework().toMvnId());
-        }
-
-        // features
-        if ( !app.getFeatureIds().isEmpty() ) {
-            JsonArrayBuilder featuresArr = Json.createArrayBuilder();
-
-            for(final ArtifactId id : app.getFeatureIds()) {
-                featuresArr.add(id.toMvnId());
-            }
-            ob.add(JSONConstants.APP_FEATURES, featuresArr.build());
-        }
-
-        // bundles
-        writeBundles(ob, app.getBundles(), app.getConfigurations());
-
-        // configurations
-        final Configurations cfgs = new Configurations();
-        for(final Configuration cfg : app.getConfigurations()) {
-            final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
-            if (  artifactProp == null ) {
-                cfgs.add(cfg);
-            }
-        }
-        writeConfigurations(ob, cfgs);
-
-        // framework properties
-        writeFrameworkProperties(ob, app.getFrameworkProperties());
-
-        // extensions
-        writeExtensions(ob, app.getExtensions(), app.getConfigurations());
-
-        JsonWriterFactory writerFactory = Json.createWriterFactory(
-                Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
-        JsonWriter jw = writerFactory.createWriter(writer);
-        jw.writeObject(ob.build());
-        jw.close();
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
deleted file mode 100644
index 5fca482..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONReader.java
+++ /dev/null
@@ -1,78 +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.io.json;
-
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.sling.feature.Configurations;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * JSON Reader for configurations.
- */
-public class ConfigurationJSONReader extends JSONReaderBase {
-
-    /**
-     * Read a map of configurations from the reader
-     * The reader is not closed. It is up to the caller to close the reader.
-     *
-     * @param reader The reader for the configuration
-     * @param location Optional location
-     * @return The read configurations
-     * @throws IOException If an IO errors occurs or the JSON is invalid.
-     */
-    public static Configurations read(final Reader reader, final String location)
-    throws IOException {
-        try {
-            final ConfigurationJSONReader mr = new ConfigurationJSONReader(location);
-            return mr.readConfigurations(reader);
-        } catch (final IllegalStateException | IllegalArgumentException e) {
-            throw new IOException(e);
-        }
-    }
-
-    /**
-     * Private constructor
-     * @param location Optional location
-     */
-    ConfigurationJSONReader(final String location) {
-        super(location);
-    }
-
-    Configurations readConfigurations(final Reader reader) throws IOException {
-        final Configurations result = new Configurations();
-
-        final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-
-        @SuppressWarnings("unchecked")
-        final Map<String, Object> map = (Map<String, Object>) JSONUtil.getValue(json);
-
-        final Map<String, Object> objMap = Collections.singletonMap(JSONConstants.FEATURE_CONFIGURATIONS, (Object)map);
-
-        readConfigurations(objMap, result);
-
-        return result;
-    }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
deleted file mode 100644
index 64e937d..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ConfigurationJSONWriter.java
+++ /dev/null
@@ -1,64 +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.io.json;
-
-import org.apache.sling.feature.Configurations;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-
-import javax.json.Json;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-
-/**
- * JSON writer for configurations
- */
-public class ConfigurationJSONWriter extends JSONWriterBase {
-
-    /**
-     * Writes the configurations to the writer.
-     * The writer is not closed.
-     * @param writer Writer
-     * @param configs List of configurations
-     * @throws IOException If writing fails
-     */
-    public static void write(final Writer writer, final Configurations configs)
-    throws IOException {
-        final ConfigurationJSONWriter w = new ConfigurationJSONWriter();
-        w.writeConfigurations(writer, configs);
-    }
-
-    private void writeConfigurations(final Writer writer, final Configurations configs)
-    throws IOException {
-        JsonObjectBuilder ob = Json.createObjectBuilder();
-
-        // TODO is this correct?
-        ob.add(JSONConstants.FEATURE_CONFIGURATIONS,
-                writeConfigurationsMap(configs));
-
-        JsonWriterFactory writerFactory = Json.createWriterFactory(
-                Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
-        JsonWriter jw = writerFactory.createWriter(writer);
-        jw.writeObject(ob.build());
-        jw.close();
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
deleted file mode 100644
index 0d21598..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
+++ /dev/null
@@ -1,431 +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.io.json;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.apache.felix.utils.resource.RequirementImpl;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.apache.sling.feature.KeyValueMap;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.json.Json;
-import javax.json.JsonObject;
-
-/**
- * This class offers a method to read a {@code Feature} using a {@code Reader} instance.
- */
-public class FeatureJSONReader extends JSONReaderBase {
-    public enum SubstituteVariables { NONE, RESOLVE, LAUNCH }
-
-    // The pattern that variables in Feature JSON follow
-    private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\{[a-zA-Z0-9.-_]+\\}");
-
-    /**
-     * Read a new feature from the reader
-     * The reader is not closed. It is up to the caller to close the reader.
-     *
-     * @param reader The reader for the feature
-     * @param location Optional location
-     * @return The read feature
-     * @throws IOException If an IO errors occurs or the JSON is invalid.
-     */
-    public static Feature read(final Reader reader, final String location, final SubstituteVariables phase)
-    throws IOException {
-        return read(reader, null, location, phase);
-    }
-
-    /**
-     * Read a new feature from the reader
-     * The reader is not closed. It is up to the caller to close the reader.
-     *
-     * @param reader The reader for the feature
-     * @param providedId Optional artifact id
-     * @param location Optional location
-     * @return The read feature
-     * @throws IOException If an IO errors occurs or the JSON is invalid.
-     */
-    public static Feature read(final Reader reader,
-            final ArtifactId providedId,
-            final String location,
-            final SubstituteVariables phase)
-    throws IOException {
-        try {
-            final FeatureJSONReader mr = new FeatureJSONReader(providedId, location, phase);
-            return mr.readFeature(reader);
-        } catch (final IllegalStateException | IllegalArgumentException e) {
-            throw new IOException(e);
-        }
-    }
-
-    /** The read feature. */
-    private Feature feature;
-
-    /** The provided id. */
-    private final ArtifactId providedId;
-
-    /** The variables from the JSON. */
-    private Map<String, String> variables;
-
-    /** The current reading phase. */
-    private final SubstituteVariables phase;
-
-    /**
-     * Private constructor
-     * @param pId Optional id
-     * @param location Optional location
-     */
-    FeatureJSONReader(final ArtifactId pId, final String location, final SubstituteVariables phase) {
-        super(location);
-        this.providedId = pId;
-        this.phase = phase;
-    }
-
-    /**
-     * Read a full feature
-     * @param reader The reader
-     * @return The feature object
-     * @throws IOException If an IO error occurs or the JSON is not valid.
-     */
-    private Feature readFeature(final Reader reader)
-    throws IOException {
-        final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-        final Map<String, Object> map = getJsonMap(json);
-
-        checkModelVersion(map);
-
-        final ArtifactId fId;
-        if ( !map.containsKey(JSONConstants.FEATURE_ID) ) {
-            if ( this.providedId == null ) {
-                throw new IOException(this.exceptionPrefix + "Feature id is missing");
-            }
-            fId = this.providedId;
-        } else {
-            final Object idObj = map.get(JSONConstants.FEATURE_ID);
-            checkType(JSONConstants.FEATURE_ID, idObj, String.class);
-            fId = ArtifactId.parse(idObj.toString());
-        }
-        this.feature = new Feature(fId);
-        this.feature.setLocation(this.location);
-
-        // title, description, vendor and license
-        this.feature.setTitle(getProperty(map, JSONConstants.FEATURE_TITLE));
-        this.feature.setDescription(getProperty(map, JSONConstants.FEATURE_DESCRIPTION));
-        this.feature.setVendor(getProperty(map, JSONConstants.FEATURE_VENDOR));
-        this.feature.setLicense(getProperty(map, JSONConstants.FEATURE_LICENSE));
-
-        this.readVariables(map, feature.getVariables());
-        this.readBundles(map, feature.getBundles(), feature.getConfigurations());
-        this.readFrameworkProperties(map, feature.getFrameworkProperties());
-        this.readConfigurations(map, feature.getConfigurations());
-
-        this.readCapabilities(map);
-        this.readRequirements(map);
-        this.readIncludes(map);
-
-        this.readExtensions(map,
-                JSONConstants.FEATURE_KNOWN_PROPERTIES,
-                this.feature.getExtensions(), this.feature.getConfigurations());
-
-        return feature;
-    }
-
-    private void checkModelVersion(final Map<String, Object> map) throws IOException {
-        String modelVersion = getProperty(map, JSONConstants.FEATURE_MODEL_VERSION);
-        if (modelVersion == null) {
-            modelVersion = "1";
-        }
-        if (!"1".equals(modelVersion)) {
-            throw new IOException("Unsupported model version: " + modelVersion);
-        }
-    }
-
-    @Override
-    protected Object handleResolveVars(Object val) {
-        if (phase == SubstituteVariables.RESOLVE) {
-            return handleVars(val);
-        } else {
-            return val;
-        }
-    }
-
-    @Override
-    protected Object handleLaunchVars(Object val) {
-        if (phase == SubstituteVariables.LAUNCH) {
-            return handleVars(val);
-        }
-        return val;
-    }
-
-    private Object handleVars(Object value) {
-        if (!(value instanceof String)) {
-            return value;
-        }
-
-        String textWithVars = (String) value;
-
-        Matcher m = VARIABLE_PATTERN.matcher(textWithVars.toString());
-        StringBuffer sb = new StringBuffer();
-        while (m.find()) {
-            String var = m.group();
-
-            int len = var.length();
-            String name = var.substring(2, len - 1);
-            String val = variables.get(name);
-            if (val != null) {
-                m.appendReplacement(sb, Matcher.quoteReplacement(val));
-            } else {
-                throw new IllegalStateException("Undefined variable: " + name);
-            }
-        }
-        m.appendTail(sb);
-
-        return sb.toString();
-    }
-
-    private void readVariables(Map<String, Object> map, KeyValueMap kvMap) throws IOException {
-        variables = new HashMap<>();
-
-        if (map.containsKey(JSONConstants.FEATURE_VARIABLES)) {
-            final Object variablesObj = map.get(JSONConstants.FEATURE_VARIABLES);
-            checkType(JSONConstants.FEATURE_VARIABLES, variablesObj, Map.class);
-
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> vars = (Map<String, Object>) variablesObj;
-            for (final Map.Entry<String, Object> entry : vars.entrySet()) {
-                checkType("variable value", entry.getValue(), String.class, Boolean.class, Number.class);
-
-                String key = entry.getKey();
-                if (kvMap.get(key) != null) {
-                    throw new IOException(this.exceptionPrefix + "Duplicate variable " + key);
-                }
-                String value = "" + entry.getValue();
-                kvMap.put(key, value);
-                variables.put(key, value);
-            }
-        }
-    }
-
-    private void readIncludes(final Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_INCLUDES)) {
-            final Object includesObj = map.get(JSONConstants.FEATURE_INCLUDES);
-            checkType(JSONConstants.FEATURE_INCLUDES, includesObj, List.class);
-
-            @SuppressWarnings("unchecked")
-            final List<Object> includes = (List<Object>)includesObj;
-            for(final Object inc : includes) {
-                checkType("Include", inc, Map.class, String.class);
-                final Include include;
-                if ( inc instanceof String ) {
-                    final ArtifactId id = ArtifactId.parse(inc.toString());
-                    include = new Include(id);
-                } else {
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> obj = (Map<String, Object>) inc;
-                    if ( !obj.containsKey(JSONConstants.ARTIFACT_ID) ) {
-                        throw new IOException(exceptionPrefix + " include is missing required artifact id");
-                    }
-                    checkType("Include " + JSONConstants.ARTIFACT_ID, obj.get(JSONConstants.ARTIFACT_ID), String.class);
-                    final ArtifactId id = ArtifactId.parse(handleResolveVars(obj.get(JSONConstants.ARTIFACT_ID)).toString());
-                    include = new Include(id);
-
-                    if ( obj.containsKey(JSONConstants.INCLUDE_REMOVALS) ) {
-                        checkType("Include removals", obj.get(JSONConstants.INCLUDE_REMOVALS), Map.class);
-                        @SuppressWarnings("unchecked")
-                        final Map<String, Object> removalObj = (Map<String, Object>) obj.get(JSONConstants.INCLUDE_REMOVALS);
-                        if ( removalObj.containsKey(JSONConstants.FEATURE_BUNDLES) ) {
-                            checkType("Include removal bundles", removalObj.get(JSONConstants.FEATURE_BUNDLES), List.class);
-                            @SuppressWarnings("unchecked")
-                            final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_BUNDLES);
-                            for(final Object val : list) {
-                                checkType("Include removal bundles", val, String.class);
-                                include.getBundleRemovals().add(ArtifactId.parse(val.toString()));
-                            }
-                        }
-                        if ( removalObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
-                            checkType("Include removal configuration", removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS), List.class);
-                            @SuppressWarnings("unchecked")
-                            final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS);
-                            for(final Object val : list) {
-                                checkType("Include removal bundles", val, String.class);
-                                include.getConfigurationRemovals().add(val.toString());
-                            }
-                        }
-                        if ( removalObj.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
-                            checkType("Include removal framework properties", removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES), List.class);
-                            @SuppressWarnings("unchecked")
-                            final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
-                            for(final Object val : list) {
-                                checkType("Include removal bundles", val, String.class);
-                                include.getFrameworkPropertiesRemovals().add(val.toString());
-                            }
-                        }
-                        if ( removalObj.containsKey(JSONConstants.INCLUDE_EXTENSION_REMOVALS) ) {
-                            checkType("Include removal extensions", removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS), List.class);
-                            @SuppressWarnings("unchecked")
-                            final List<Object> list = (List<Object>)removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
-                            for(final Object val : list) {
-                                checkType("Include removal extension", val, String.class, Map.class);
-                                if ( val instanceof String ) {
-                                    include.getExtensionRemovals().add(val.toString());
-                                } else {
-                                    @SuppressWarnings("unchecked")
-                                    final Map<String, Object> removalMap = (Map<String, Object>)val;
-                                    final Object nameObj = removalMap.get("name");
-                                    checkType("Include removal extension", nameObj, String.class);
-                                    if ( removalMap.containsKey("artifacts") ) {
-                                        checkType("Include removal extension artifacts", removalMap.get("artifacts"), List.class);
-                                        @SuppressWarnings("unchecked")
-                                        final List<Object> artifactList = (List<Object>)removalMap.get("artifacts");
-                                        final List<ArtifactId> ids = new ArrayList<>();
-                                        for(final Object aid : artifactList) {
-                                            checkType("Include removal extension artifact", aid, String.class);
-                                            ids.add(ArtifactId.parse(aid.toString()));
-                                        }
-                                        include.getArtifactExtensionRemovals().put(nameObj.toString(), ids);
-                                    } else {
-                                        include.getExtensionRemovals().add(nameObj.toString());
-                                    }
-                                }
-                            }
-                        }
-
-                    }
-                }
-                for(final Include i : feature.getIncludes()) {
-                    if ( i.getId().equals(include.getId()) ) {
-                        throw new IOException(exceptionPrefix + "Duplicate include of " + include.getId());
-                    }
-                }
-                feature.getIncludes().add(include);
-            }
-        }
-    }
-
-    private void readRequirements(Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_REQUIREMENTS)) {
-            final Object reqObj = map.get(JSONConstants.FEATURE_REQUIREMENTS);
-            checkType(JSONConstants.FEATURE_REQUIREMENTS, reqObj, List.class);
-
-            @SuppressWarnings("unchecked")
-            final List<Object> requirements = (List<Object>)reqObj;
-            for(final Object req : requirements) {
-                checkType("Requirement", req, Map.class);
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> obj = (Map<String, Object>) req;
-
-                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
-                    throw new IOException(this.exceptionPrefix + "Namespace is missing for requirement");
-                }
-                checkType("Requirement namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
-                Map<String, Object> attrMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
-                    checkType("Requirement attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
-                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, handleResolveVars(value), attrMap::put)));
-                }
-
-                Map<String, String> dirMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
-                    checkType("Requirement directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> dirs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_DIRECTIVES);
-                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, handleResolveVars(value), dirMap::put)));
-                }
-
-                final Requirement r = new RequirementImpl(null, handleResolveVars(obj.get(JSONConstants.REQCAP_NAMESPACE)).toString(), dirMap, attrMap);
-                feature.getRequirements().add(r);
-            }
-        }
-    }
-
-    private void readCapabilities(Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_CAPABILITIES)) {
-            final Object capObj = map.get(JSONConstants.FEATURE_CAPABILITIES);
-            checkType(JSONConstants.FEATURE_CAPABILITIES, capObj, List.class);
-
-            @SuppressWarnings("unchecked")
-            final List<Object> capabilities = (List<Object>)capObj;
-            for(final Object cap : capabilities) {
-                checkType("Capability", cap, Map.class);
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> obj = (Map<String, Object>) cap;
-
-                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
-                    throw new IOException(this.exceptionPrefix + "Namespace is missing for capability");
-                }
-                checkType("Capability namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
-                Map<String, Object> attrMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
-                    checkType("Capability attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
-                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, handleResolveVars(value), attrMap::put)));
-                }
-
-                Map<String, String> dirMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
-                    checkType("Capability directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> dirs = (Map<String, Object>) obj.get(JSONConstants.REQCAP_DIRECTIVES);
-                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, handleResolveVars(value), dirMap::put)));
-                }
-
-                final Capability c = new CapabilityImpl(null, handleResolveVars(obj.get(JSONConstants.REQCAP_NAMESPACE)).toString(), dirMap, attrMap);
-                feature.getCapabilities().add(c);
-            }
-        }
-    }
-
-    @FunctionalInterface
-    private interface BiConsumer_WithExceptions<T, V, E extends Exception> {
-        void accept(T t, V u) throws E;
-    }
-
-    private static <T, V, E extends Exception> BiConsumer<T, V> rethrowBiConsumer(BiConsumer_WithExceptions<T, V, E> biConsumer) {
-        return (t, u) -> {
-            try {
-                biConsumer.accept(t, u);
-            } catch (Exception exception) {
-                throwAsUnchecked(exception);
-            }
-        };
-    }
-
-    @SuppressWarnings ("unchecked")
-    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
-        throw (E) exception;
-    }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
deleted file mode 100644
index 57428e1..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
+++ /dev/null
@@ -1,207 +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.io.json;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGenerator;
-
-/**
- * Simple JSON writer for a feature
- */
-public class FeatureJSONWriter extends JSONWriterBase {
-    private FeatureJSONWriter() {}
-
-    /**
-     * Writes the feature to the writer.
-     * The writer is not closed.
-     * @param writer Writer
-     * @param feature Feature
-     * @throws IOException If writing fails
-     */
-    public static void write(final Writer writer, final Feature feature)
-    throws IOException {
-        final FeatureJSONWriter w = new FeatureJSONWriter();
-        w.writeFeature(writer, feature);
-    }
-
-    private void writeProperty(final JsonObjectBuilder ob, final String key, final String value) {
-        if ( value != null ) {
-            ob.add(key, value);
-        }
-    }
-
-    private void writeFeature(final Writer writer, final Feature feature)
-    throws IOException {
-        JsonObjectBuilder ob = Json.createObjectBuilder();
-        ob.add(JSONConstants.FEATURE_ID, feature.getId().toMvnId());
-
-        // title, description, vendor, license
-        writeProperty(ob, JSONConstants.FEATURE_TITLE, feature.getTitle());
-        writeProperty(ob, JSONConstants.FEATURE_DESCRIPTION, feature.getDescription());
-        writeProperty(ob, JSONConstants.FEATURE_VENDOR, feature.getVendor());
-        writeProperty(ob, JSONConstants.FEATURE_LICENSE, feature.getLicense());
-
-        // variables
-        writeVariables(ob, feature.getVariables());
-
-        // includes
-        if ( !feature.getIncludes().isEmpty() ) {
-            JsonArrayBuilder incArray = Json.createArrayBuilder();
-            for(final Include inc : feature.getIncludes()) {
-                if ( inc.getArtifactExtensionRemovals().isEmpty()
-                     && inc.getBundleRemovals().isEmpty()
-                     && inc.getConfigurationRemovals().isEmpty()
-                     && inc.getFrameworkPropertiesRemovals().isEmpty() ) {
-                    incArray.add(inc.getId().toMvnId());
-                } else {
-                    JsonObjectBuilder includeObj = Json.createObjectBuilder();
-                    includeObj.add(JSONConstants.ARTIFACT_ID, inc.getId().toMvnId());
-
-                    JsonObjectBuilder removalsObj = Json.createObjectBuilder();
-                    if ( !inc.getArtifactExtensionRemovals().isEmpty()
-                         || inc.getExtensionRemovals().isEmpty() ) {
-                        JsonArrayBuilder extRemovals = Json.createArrayBuilder();
-                        for(final String id : inc.getExtensionRemovals()) {
-                            extRemovals.add(id);
-                        }
-                        for(final Map.Entry<String, List<ArtifactId>> entry : inc.getArtifactExtensionRemovals().entrySet()) {
-                            JsonArrayBuilder ab = Json.createArrayBuilder();
-                            for(final ArtifactId id : entry.getValue()) {
-                                ab.add(id.toMvnId());
-                            }
-                            extRemovals.add(Json.createObjectBuilder().add(entry.getKey(),
-                                    ab.build()).build());
-                        }
-                        removalsObj.add(JSONConstants.INCLUDE_EXTENSION_REMOVALS, extRemovals.build());
-                    }
-                    if ( !inc.getConfigurationRemovals().isEmpty() ) {
-                        JsonArrayBuilder cfgRemovals = Json.createArrayBuilder();
-                        for(final String val : inc.getConfigurationRemovals()) {
-                            cfgRemovals.add(val);
-                        }
-                        removalsObj.add(JSONConstants.FEATURE_CONFIGURATIONS, cfgRemovals.build());
-                    }
-                    if ( !inc.getBundleRemovals().isEmpty() ) {
-                        JsonArrayBuilder bundleRemovals = Json.createArrayBuilder();
-                        for(final ArtifactId val : inc.getBundleRemovals()) {
-                            bundleRemovals.add(val.toMvnId());
-                        }
-                        removalsObj.add(JSONConstants.FEATURE_BUNDLES, bundleRemovals.build());
-                    }
-                    if ( !inc.getFrameworkPropertiesRemovals().isEmpty() ) {
-                        JsonArrayBuilder propRemovals = Json.createArrayBuilder();
-                        for(final String val : inc.getFrameworkPropertiesRemovals()) {
-                            propRemovals.add(val);
-                        }
-                        removalsObj.add(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propRemovals.build());
-                    }
-                    includeObj.add(JSONConstants.INCLUDE_REMOVALS, removalsObj.build());
-
-                    incArray.add(includeObj.build());
-                }
-            }
-            ob.add(JSONConstants.FEATURE_INCLUDES, incArray.build());
-        }
-
-        // requirements
-        if ( !feature.getRequirements().isEmpty() ) {
-            JsonArrayBuilder requirements = Json.createArrayBuilder();
-
-            for(final Requirement req : feature.getRequirements()) {
-                JsonObjectBuilder requirementObj = Json.createObjectBuilder();
-                requirementObj.add(JSONConstants.REQCAP_NAMESPACE, req.getNamespace());
-                if ( !req.getAttributes().isEmpty() ) {
-                    JsonObjectBuilder attrObj = Json.createObjectBuilder();
-                    req.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, attrObj::add));
-                    requirementObj.add(JSONConstants.REQCAP_ATTRIBUTES, attrObj.build());
-                }
-                if ( !req.getDirectives().isEmpty() ) {
-                    JsonObjectBuilder reqObj = Json.createObjectBuilder();
-                    req.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, reqObj::add));
-                    requirementObj.add(JSONConstants.REQCAP_DIRECTIVES, reqObj.build());
-                }
-                requirements.add(requirementObj.build());
-            }
-            ob.add(JSONConstants.FEATURE_REQUIREMENTS, requirements.build());
-        }
-
-        // capabilities
-        if ( !feature.getCapabilities().isEmpty() ) {
-            JsonArrayBuilder capabilities = Json.createArrayBuilder();
-
-            for(final Capability cap : feature.getCapabilities()) {
-                JsonObjectBuilder capabilityObj = Json.createObjectBuilder();
-                capabilityObj.add(JSONConstants.REQCAP_NAMESPACE, cap.getNamespace());
-                if ( !cap.getAttributes().isEmpty() ) {
-                    JsonObjectBuilder attrObj = Json.createObjectBuilder();
-                    cap.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, attrObj::add));
-                    capabilityObj.add(JSONConstants.REQCAP_ATTRIBUTES, attrObj.build());
-                }
-                if ( !cap.getDirectives().isEmpty() ) {
-                    JsonObjectBuilder reqObj = Json.createObjectBuilder();
-                    cap.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, reqObj::add));
-                    capabilityObj.add(JSONConstants.REQCAP_DIRECTIVES, reqObj.build());
-                }
-                capabilities.add(capabilityObj.build());
-            }
-            ob.add(JSONConstants.FEATURE_CAPABILITIES, capabilities.build());
-        }
-
-        // bundles
-        writeBundles(ob, feature.getBundles(), feature.getConfigurations());
-
-        // configurations
-        final Configurations cfgs = new Configurations();
-        for(final Configuration cfg : feature.getConfigurations()) {
-            final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
-            if (  artifactProp == null ) {
-                cfgs.add(cfg);
-            }
-        }
-        writeConfigurations(ob, cfgs);
-
-        // framework properties
-        writeFrameworkProperties(ob, feature.getFrameworkProperties());
-
-        // extensions
-        writeExtensions(ob, feature.getExtensions(), feature.getConfigurations());
-
-        JsonWriterFactory writerFactory = Json.createWriterFactory(
-                Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
-        JsonWriter jw = writerFactory.createWriter(writer);
-        jw.writeObject(ob.build());
-        jw.close();
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java
deleted file mode 100644
index 3b6f707..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONConstants.java
+++ /dev/null
@@ -1,88 +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.io.json;
-
-import org.apache.sling.feature.Configuration;
-
-import java.util.Arrays;
-import java.util.List;
-
-public abstract class JSONConstants {
-
-    public static final String FEATURE_ID = "id";
-
-    public static final String FEATURE_VARIABLES = "variables";
-
-    public static final String FEATURE_BUNDLES = "bundles";
-
-    public static final String FEATURE_FRAMEWORK_PROPERTIES = "framework-properties";
-
-    public static final String FEATURE_CONFIGURATIONS = "configurations";
-
-    public static final String FEATURE_INCLUDES = "includes";
-
-    public static final String FEATURE_REQUIREMENTS = "requirements";
-
-    public static final String FEATURE_CAPABILITIES = "capabilities";
-
-    public static final String FEATURE_TITLE = "title";
-
-    public static final String FEATURE_DESCRIPTION = "description";
-
-    public static final String FEATURE_VENDOR = "vendor";
-
-    public static final String FEATURE_LICENSE = "license";
-
-    public static final String FEATURE_MODEL_VERSION = "model-version";
-
-    public static final List<String> FEATURE_KNOWN_PROPERTIES = Arrays.asList(FEATURE_ID,
-            FEATURE_MODEL_VERSION,
-            FEATURE_VARIABLES,
-            FEATURE_BUNDLES,
-            FEATURE_FRAMEWORK_PROPERTIES,
-            FEATURE_CONFIGURATIONS,
-            FEATURE_INCLUDES,
-            FEATURE_REQUIREMENTS,
-            FEATURE_CAPABILITIES,
-            FEATURE_TITLE,
-            FEATURE_DESCRIPTION,
-            FEATURE_VENDOR,
-            FEATURE_LICENSE);
-
-    public static final String ARTIFACT_ID = "id";
-
-    public static final List<String> ARTIFACT_KNOWN_PROPERTIES = Arrays.asList(ARTIFACT_ID,
-            Configuration.PROP_ARTIFACT,
-            FEATURE_CONFIGURATIONS);
-
-    public static final String INCLUDE_REMOVALS = "removals";
-
-    public static final String INCLUDE_EXTENSION_REMOVALS = "extensions";
-
-    public static final String REQCAP_NAMESPACE = "namespace";
-    public static final String REQCAP_ATTRIBUTES = "attributes";
-    public static final String REQCAP_DIRECTIVES = "directives";
-
-    public static final String APP_FRAMEWORK = "frameworkId";
-    public static final String APP_FEATURES = "features";
-
-    public static final List<String> APP_KNOWN_PROPERTIES = Arrays.asList(APP_FRAMEWORK,
-            FEATURE_BUNDLES,
-            FEATURE_FRAMEWORK_PROPERTIES,
-            FEATURE_CONFIGURATIONS,
-            APP_FEATURES);
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
deleted file mode 100644
index fe3b89e..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
+++ /dev/null
@@ -1,479 +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.io.json;
-
-import org.apache.felix.configurator.impl.json.JSMin;
-import org.apache.felix.configurator.impl.json.JSONUtil;
-import org.apache.felix.configurator.impl.json.TypeConverter;
-import org.apache.felix.configurator.impl.model.Config;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.KeyValueMap;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-import javax.json.JsonWriter;
-
-/**
- * Common methods for JSON reading.
- */
-abstract class JSONReaderBase {
-
-    /** The optional location. */
-    protected final String location;
-
-    /** Exception prefix containing the location (if set) */
-    protected final String exceptionPrefix;
-
-    /**
-     * Private constructor
-     * @param location Optional location
-     */
-    JSONReaderBase(final String location) {
-        this.location = location;
-        if ( location == null ) {
-            exceptionPrefix = "";
-        } else {
-            exceptionPrefix = location + " : ";
-        }
-    }
-
-    protected String minify(final Reader reader) throws IOException {
-       // minify JSON (remove comments)
-        final String contents;
-        try ( final Writer out = new StringWriter()) {
-            final JSMin min = new JSMin(reader, out);
-            min.jsmin();
-            contents = out.toString();
-        }
-        return contents;
-    }
-
-    /** Get the JSON object as a map, removing all comments that start with a '#' character
-     */
-    protected Map<String, Object> getJsonMap(JsonObject json) {
-        @SuppressWarnings("unchecked")
-        Map<String, Object> m = (Map<String, Object>) JSONUtil.getValue(json);
-
-        removeComments(m);
-        return m;
-    }
-
-    private void removeComments(Map<String, Object> m) {
-        for(Iterator<Map.Entry<String, Object>> it = m.entrySet().iterator(); it.hasNext(); ) {
-            Entry<String, ?> entry = it.next();
-            if (entry.getKey().startsWith("#")) {
-                it.remove();
-            } else if (entry.getValue() instanceof Map) {
-                @SuppressWarnings("unchecked")
-                Map<String, Object> embedded = (Map<String, Object>) entry.getValue();
-                removeComments(embedded);
-            } else if (entry.getValue() instanceof Collection) {
-                Collection<?> embedded = (Collection<?>) entry.getValue();
-                removeComments(embedded);
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private void removeComments(Collection<?> embedded) {
-        for (Object el : embedded) {
-            if (el instanceof Collection) {
-                removeComments((Collection<?>) el);
-            } else if (el instanceof Map) {
-                removeComments((Map<String, Object>) el);
-            }
-        }
-    }
-
-    protected String getProperty(final Map<String, Object> map, final String key) throws IOException {
-        final Object val = map.get(key);
-        if ( val != null ) {
-            checkType(key, val, String.class);
-            return val.toString();
-        }
-        return null;
-    }
-
-    /**
-     * Read the bundles / start levels section
-     * @param map The map describing the feature
-     * @param container The bundles container
-     * @param configContainer The configurations container
-     * @throws IOException If the json is invalid.
-     */
-    protected void readBundles(
-            final Map<String, Object> map,
-            final Bundles container,
-            final Configurations configContainer) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_BUNDLES)) {
-            final Object bundlesObj = map.get(JSONConstants.FEATURE_BUNDLES);
-            checkType(JSONConstants.FEATURE_BUNDLES, bundlesObj, List.class);
-
-            final List<Artifact> list = new ArrayList<>();
-            readArtifacts(JSONConstants.FEATURE_BUNDLES, "bundle", list, bundlesObj, configContainer);
-
-            for(final Artifact a : list) {
-                Artifact sameFound = container.getSame(a.getId());
-                if ( sameFound != null) {
-                    String str1 = a.getMetadata().get("run-modes");
-                    String str2 = sameFound.getMetadata().get("run-modes");
-
-                    if (str1 == null ? str2 == null : str1.equals(str2)) {
-                        throw new IOException(exceptionPrefix + "Duplicate bundle " + a.getId().toMvnId());
-                    }
-                }
-                try {
-                    // check start order
-                    a.getStartOrder();
-                } catch ( final IllegalArgumentException nfe) {
-                    throw new IOException(exceptionPrefix + "Illegal start order '" + a.getMetadata().get(Artifact.KEY_START_ORDER) + "'");
-                }
-                container.add(a);
-            }
-        }
-    }
-
-    protected void readArtifacts(final String section,
-            final String artifactType,
-            final List<Artifact> artifacts,
-            final Object listObj,
-            final Configurations container)
-    throws IOException {
-        checkType(section, listObj, List.class);
-        @SuppressWarnings("unchecked")
-        final List<Object> list = (List<Object>) listObj;
-        for(final Object entry : list) {
-            final Artifact artifact;
-            checkType(artifactType, entry, Map.class, String.class);
-            if ( entry instanceof String ) {
-                artifact = new Artifact(ArtifactId.parse(handleResolveVars(entry).toString()));
-            } else {
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> bundleObj = (Map<String, Object>) entry;
-                if ( !bundleObj.containsKey(JSONConstants.ARTIFACT_ID) ) {
-                    throw new IOException(exceptionPrefix + " " + artifactType + " is missing required artifact id");
-                }
-                checkType(artifactType + " " + JSONConstants.ARTIFACT_ID, bundleObj.get(JSONConstants.ARTIFACT_ID), String.class);
-                final ArtifactId id = ArtifactId.parse(handleResolveVars(bundleObj.get(JSONConstants.ARTIFACT_ID)).toString());
-
-                artifact = new Artifact(id);
-                for(final Map.Entry<String, Object> metadataEntry : bundleObj.entrySet()) {
-                    final String key = metadataEntry.getKey();
-                    if ( JSONConstants.ARTIFACT_KNOWN_PROPERTIES.contains(key) ) {
-                        continue;
-                    }
-                    checkType(artifactType + " metadata " + key, metadataEntry.getValue(), String.class, Number.class, Boolean.class);
-                    artifact.getMetadata().put(key, metadataEntry.getValue().toString());
-                }
-                if ( bundleObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
-                    checkType(artifactType + " configurations", bundleObj.get(JSONConstants.FEATURE_CONFIGURATIONS), Map.class);
-                    List<Configuration> bundleConfigs = addConfigurations(bundleObj, artifact, container);
-                    artifact.getMetadata().put(JSONConstants.FEATURE_CONFIGURATIONS, bundleConfigs);
-                }
-            }
-            artifacts.add(artifact);
-        }
-    }
-
-    /** Substitutes variables that need to be specified before the resolver executes.
-     * These are variables in features, artifacts (such as bundles), requirements
-     * and capabilities.
-     * @param val The value that may contain a variable.
-     * @return The value with the variable substitiuted.
-     */
-    protected Object handleResolveVars(Object val) {
-        // No variable substitution at this level, but subclasses can add this in
-        return val;
-    }
-
-    /** Substitutes variables that need to be substituted at launch time.
-     * These are all variables that are not needed by the resolver.
-     * @param val The value that may contain a variable.
-     * @return The value with the variable substitiuted.
-     */
-    protected Object handleLaunchVars(Object val) {
-        // No variable substitution at this level, but subclasses can add this in
-        return val;
-    }
-
-    protected List<Configuration> addConfigurations(final Map<String, Object> map,
-            final Artifact artifact,
-            final Configurations container) throws IOException {
-        final JSONUtil.Report report = new JSONUtil.Report();
-        @SuppressWarnings("unchecked")
-        final List<Config> configs = JSONUtil.readConfigurationsJSON(new TypeConverter(null),
-                0, "", (Map<String, ?>)map.get(JSONConstants.FEATURE_CONFIGURATIONS), report);
-        if ( !report.errors.isEmpty() || !report.warnings.isEmpty() ) {
-            final StringBuilder builder = new StringBuilder(exceptionPrefix);
-            builder.append("Errors in configurations:");
-            for(final String w : report.warnings) {
-                builder.append("\n");
-                builder.append(w);
-            }
-            for(final String e : report.errors) {
-                builder.append("\n");
-                builder.append(e);
-            }
-            throw new IOException(builder.toString());
-        }
-
-        List<Configuration> newConfigs = new ArrayList<>();
-        for(final Config c : configs) {
-            final int pos = c.getPid().indexOf('~');
-            final Configuration config;
-            if ( pos != -1 ) {
-                config = new Configuration(c.getPid().substring(0, pos), c.getPid().substring(pos + 1));
-            } else {
-                config = new Configuration(c.getPid());
-            }
-            final Enumeration<String> keyEnum = c.getProperties().keys();
-            while ( keyEnum.hasMoreElements() ) {
-                final String key = keyEnum.nextElement();
-                if ( key.startsWith(":configurator:") ) {
-                    throw new IOException(exceptionPrefix + "Configuration must not define configurator property " + key);
-                }
-                final Object val = c.getProperties().get(key);
-                config.getProperties().put(key, handleLaunchVars(val));
-            }
-            if ( config.getProperties().get(Configuration.PROP_ARTIFACT) != null ) {
-                throw new IOException(exceptionPrefix + "Configuration must not define property " + Configuration.PROP_ARTIFACT);
-            }
-            if ( artifact != null ) {
-                config.getProperties().put(Configuration.PROP_ARTIFACT, artifact.getId().toMvnId());
-            }
-            for(final Configuration current : container) {
-                if ( current.equals(config) ) {
-                    throw new IOException(exceptionPrefix + "Duplicate configuration " + config);
-                }
-            }
-            container.add(config);
-            newConfigs.add(config);
-        }
-        return newConfigs;
-    }
-
-
-    protected void readConfigurations(final Map<String, Object> map,
-            final Configurations container) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
-            checkType(JSONConstants.FEATURE_CONFIGURATIONS, map.get(JSONConstants.FEATURE_CONFIGURATIONS), Map.class);
-            addConfigurations(map, null, container);
-        }
-    }
-
-    protected void readFrameworkProperties(final Map<String, Object> map,
-            final KeyValueMap container) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
-            final Object propsObj= map.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
-            checkType(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propsObj, Map.class);
-
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> props = (Map<String, Object>) propsObj;
-            for(final Map.Entry<String, Object> entry : props.entrySet()) {
-                checkType("framework property value", entry.getValue(), String.class, Boolean.class, Number.class);
-                if ( container.get(entry.getKey()) != null ) {
-                    throw new IOException(this.exceptionPrefix + "Duplicate framework property " + entry.getKey());
-                }
-                container.put(entry.getKey(), handleLaunchVars(entry.getValue()).toString());
-            }
-
-        }
-    }
-
-    protected void readExtensions(final Map<String, Object> map,
-            final List<String> keywords,
-            final Extensions container,
-            final Configurations configContainer) throws IOException {
-        final Set<String> keySet = new HashSet<>(map.keySet());
-        keySet.removeAll(keywords);
-        // the remaining keys are considered extensions!
-        for(final String key : keySet) {
-            final int pos = key.indexOf(':');
-            final String postfix = pos == -1 ? null : key.substring(pos + 1);
-            final int sep = (postfix == null ? key.indexOf('|') : postfix.indexOf('|'));
-            final String name;
-            final String type;
-            final String optional;
-            if ( pos == -1 ) {
-                type = ExtensionType.ARTIFACTS.name();
-                if ( sep == -1 ) {
-                    name = key;
-                    optional = Boolean.FALSE.toString();
-                } else {
-                    name = key.substring(0, sep);
-                    optional = key.substring(sep + 1);
-                }
-            } else {
-                name = key.substring(0, pos);
-                if ( sep == -1 ) {
-                    type = postfix;
-                    optional = Boolean.FALSE.toString();
-                } else {
-                    type = postfix.substring(0, sep);
-                    optional = postfix.substring(sep + 1);
-                }
-            }
-            if ( JSONConstants.APP_KNOWN_PROPERTIES.contains(name) ) {
-                throw new IOException(this.exceptionPrefix + "Extension is using reserved name : " + name);
-            }
-            if ( JSONConstants.FEATURE_KNOWN_PROPERTIES.contains(name) ) {
-                throw new IOException(this.exceptionPrefix + "Extension is using reserved name : " + name);
-            }
-            if ( container.getByName(name) != null ) {
-                throw new IOException(exceptionPrefix + "Duplicate extension with name " + name);
-            }
-
-            final ExtensionType extType = ExtensionType.valueOf(type);
-            final boolean opt = Boolean.valueOf(optional).booleanValue();
-
-            final Extension ext = new Extension(extType, name, opt);
-            final Object value = map.get(key);
-            switch ( extType ) {
-                case ARTIFACTS : final List<Artifact> list = new ArrayList<>();
-                                 readArtifacts("Extension " + name, "artifact", list, value, configContainer);
-                                 for(final Artifact a : list) {
-                                     if ( ext.getArtifacts().contains(a) ) {
-                                         throw new IOException(exceptionPrefix + "Duplicate artifact in extension " + name + " : " + a.getId().toMvnId());
-                                     }
-                                     ext.getArtifacts().add(a);
-                                 }
-                                 break;
-                case JSON : checkType("JSON Extension " + name, value, Map.class, List.class);
-                            final JsonStructure struct = build(value);
-                            try ( final StringWriter w = new StringWriter()) {
-                                final JsonWriter jw = Json.createWriter(w);
-                                jw.write(struct);
-                                w.flush();
-                                ext.setJSON(w.toString());
-                            }
-                            break;
-                case TEXT : checkType("Text Extension " + name, value, String.class, List.class);
-                            if ( value instanceof String ) {
-                                // string
-                                ext.setText(value.toString());
-                            } else {
-                                // list (array of strings)
-                                @SuppressWarnings("unchecked")
-                                final List<Object> l = (List<Object>)value;
-                                final StringBuilder sb = new StringBuilder();
-                                for(final Object o : l) {
-                                    checkType("Text Extension " + name + ", value " + o, o, String.class);
-                                    sb.append(o.toString());
-                                    sb.append('\n');
-                                }
-                                ext.setText(sb.toString());
-                            }
-                            break;
-            }
-
-            container.add(ext);
-        }
-    }
-
-    private JsonStructure build(final Object value) {
-        if ( value instanceof List ) {
-            @SuppressWarnings("unchecked")
-            final List<Object> list = (List<Object>)value;
-            final JsonArrayBuilder builder = Json.createArrayBuilder();
-            for(final Object obj : list) {
-                if ( obj instanceof String ) {
-                    builder.add(obj.toString());
-                } else if ( obj instanceof Long ) {
-                    builder.add((Long)obj);
-                } else if ( obj instanceof Double ) {
-                    builder.add((Double)obj);
-                } else if (obj instanceof Boolean ) {
-                    builder.add((Boolean)obj);
-                } else if ( obj instanceof Map ) {
-                    builder.add(build(obj));
-                } else if ( obj instanceof List ) {
-                    builder.add(build(obj));
-                }
-
-            }
-            return builder.build();
-        } else if ( value instanceof Map ) {
-            @SuppressWarnings("unchecked")
-            final Map<String, Object> map = (Map<String, Object>)value;
-            final JsonObjectBuilder builder = Json.createObjectBuilder();
-            for(final Map.Entry<String, Object> entry : map.entrySet()) {
-                if ( entry.getValue() instanceof String ) {
-                    builder.add(entry.getKey(), entry.getValue().toString());
-                } else if ( entry.getValue() instanceof Long ) {
-                    builder.add(entry.getKey(), (Long)entry.getValue());
-                } else if ( entry.getValue() instanceof Double ) {
-                    builder.add(entry.getKey(), (Double)entry.getValue());
-                } else if ( entry.getValue() instanceof Boolean ) {
-                    builder.add(entry.getKey(), (Boolean)entry.getValue());
-                } else if ( entry.getValue() instanceof Map ) {
-                    builder.add(entry.getKey(), build(entry.getValue()));
-                } else if ( entry.getValue() instanceof List ) {
-                    builder.add(entry.getKey(), build(entry.getValue()));
-                }
-            }
-            return builder.build();
-        }
-        return null;
-    }
-
-    /**
-     * Check if the value is one of the provided types
-     * @param key A key for the error message
-     * @param val The value to check
-     * @param types The allowed types
-     * @throws IOException If the val is not of the specified types
-     */
-    protected void checkType(final String key, final Object val, Class<?>...types) throws IOException {
-        boolean valid = false;
-        for(final Class<?> c : types) {
-            if ( c.isInstance(val) ) {
-                valid = true;
-                break;
-            }
-        }
-        if ( !valid ) {
-            throw new IOException(this.exceptionPrefix + "Key " + key + " is not one of the allowed types " + Arrays.toString(types) + " : " + val.getClass());
-        }
-    }
-}
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
deleted file mode 100644
index ff502af..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
+++ /dev/null
@@ -1,259 +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.io.json;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.KeyValueMap;
-
-import java.io.StringReader;
-import java.lang.reflect.Array;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-
-/**
- * Common functionality for writing JSON
- */
-abstract class JSONWriterBase {
-    protected void writeBundles(final JsonObjectBuilder ob,
-            final Bundles bundles,
-            final Configurations allConfigs) {
-        // bundles
-        if ( !bundles.isEmpty() ) {
-            JsonArrayBuilder bundleArray = Json.createArrayBuilder();
-
-            for(final Artifact artifact : bundles) {
-                final Configurations cfgs = new Configurations();
-                for(final Configuration cfg : allConfigs) {
-                    String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
-                    if (artifactProp != null) {
-                        if (artifactProp.startsWith("mvn:")) {
-                            // Change Maven URL to maven GAV syntax
-                            artifactProp = artifactProp.substring("mvn:".length());
-                            artifactProp = artifactProp.replace('/', ':');
-                        }
-                        if (artifact.getId().toMvnId().equals(artifactProp)) {
-                            cfgs.add(cfg);
-                        }
-                    }
-                }
-                KeyValueMap md = artifact.getMetadata();
-                if ( md.isEmpty() && cfgs.isEmpty() ) {
-                    bundleArray.add(artifact.getId().toMvnId());
-                } else {
-                    JsonObjectBuilder bundleObj = Json.createObjectBuilder();
-                    bundleObj.add(JSONConstants.ARTIFACT_ID, artifact.getId().toMvnId());
-
-                    if (md.get("start-level") == null) {
-                        String so = md.get("start-order");
-                        if (so != null) {
-                            md.put("start-level", so);
-                        }
-                    }
-
-                    Object runmodes = md.remove("runmodes");
-                    if (runmodes instanceof String) {
-                        md.put("run-modes", runmodes);
-                    }
-
-                    for(final Map.Entry<String, String> me : md) {
-                        bundleObj.add(me.getKey(), me.getValue());
-                    }
-
-                    writeConfigurations(bundleObj, cfgs);
-
-                    bundleArray.add(bundleObj.build());
-                }
-            }
-            ob.add(JSONConstants.FEATURE_BUNDLES, bundleArray.build());
-        }
-    }
-
-    /**
-     * Write the list of configurations into a "configurations" element
-     * @param ob The json generator
-     * @param cfgs The list of configurations
-     */
-    protected void writeConfigurations(final JsonObjectBuilder ob, final Configurations cfgs) {
-        if ( !cfgs.isEmpty() ) {
-            ob.add(JSONConstants.FEATURE_CONFIGURATIONS,
-                    writeConfigurationsMap(cfgs));
-        }
-    }
-
-    /**
-     * Write the list of configurations into a "configurations" element
-     * @param w The json generator
-     * @param cfgs The list of configurations
-     * @return
-     */
-    protected JsonObject writeConfigurationsMap(final Configurations cfgs) {
-        JsonObjectBuilder configObj = Json.createObjectBuilder();
-        for(final Configuration cfg : cfgs) {
-            final String key;
-            if ( cfg.isFactoryConfiguration() ) {
-                key = cfg.getFactoryPid() + "~" + cfg.getName();
-            } else {
-                key = cfg.getPid();
-            }
-            JsonObjectBuilder cfgValObj = Json.createObjectBuilder();
-
-            final Enumeration<String> e = cfg.getProperties().keys();
-            while ( e.hasMoreElements() ) {
-                final String name = e.nextElement();
-                if ( Configuration.PROP_ARTIFACT.equals(name) ) {
-                    continue;
-                }
-
-                final Object val = cfg.getProperties().get(name);
-
-                String typePostFix = null;
-                final Object typeCheck;
-                if ( val.getClass().isArray() ) {
-                    if ( Array.getLength(val) > 0 ) {
-                        typeCheck = Array.get(val, 0);
-                    } else {
-                        typeCheck = null;
-                    }
-                } else {
-                    typeCheck = val;
-                }
-
-                if ( typeCheck instanceof Integer ) {
-                    typePostFix = ":Integer";
-                } else if ( typeCheck instanceof Byte ) {
-                    typePostFix = ":Byte";
-                } else if ( typeCheck instanceof Character ) {
-                    typePostFix = ":Character";
-                } else if ( typeCheck instanceof Float ) {
-                    typePostFix = ":Float";
-                }
-
-                if ( val.getClass().isArray() ) {
-                    JsonArrayBuilder ab = Json.createArrayBuilder();
-                    for(int i=0; i<Array.getLength(val);i++ ) {
-                        final Object obj = Array.get(val, i);
-                        if ( typePostFix == null ) {
-                            if ( obj instanceof String ) {
-                                ab.add((String)obj);
-                            } else if ( obj instanceof Boolean ) {
-                                ab.add((Boolean)obj);
-                            } else if ( obj instanceof Long ) {
-                                ab.add((Long)obj);
-                            } else if ( obj instanceof Double ) {
-                                ab.add((Double)obj);
-                            }
-                        } else {
-                            ab.add(obj.toString());
-                        }
-                    }
-                    cfgValObj.add(name, ab.build());
-                } else {
-                    if ( typePostFix == null ) {
-                        if ( val instanceof String ) {
-                            cfgValObj.add(name, (String)val);
-                        } else if ( val instanceof Boolean ) {
-                            cfgValObj.add(name, (Boolean)val);
-                        } else if ( val instanceof Long ) {
-                            cfgValObj.add(name, (Long)val);
-                        } else if ( val instanceof Double ) {
-                            cfgValObj.add(name, (Double)val);
-                        }
-                    } else {
-                        cfgValObj.add(name + typePostFix, val.toString());
-                    }
-                }
-            }
-            configObj.add(key, cfgValObj.build());
-        }
-        return configObj.build();
-    }
-
-    protected void writeVariables(final JsonObjectBuilder ob, final KeyValueMap vars) {
-        if ( !vars.isEmpty()) {
-            JsonObjectBuilder varsObj = Json.createObjectBuilder();
-            for (final Map.Entry<String, String> entry : vars) {
-                varsObj.add(entry.getKey(), entry.getValue());
-            }
-            ob.add(JSONConstants.FEATURE_VARIABLES, varsObj.build());
-        }
-    }
-
-    protected void writeFrameworkProperties(final JsonObjectBuilder ob, final KeyValueMap props) {
-        // framework properties
-        if ( !props.isEmpty() ) {
-            JsonObjectBuilder propsObj = Json.createObjectBuilder();
-            for(final Map.Entry<String, String> entry : props) {
-                propsObj.add(entry.getKey(), entry.getValue());
-            }
-            ob.add(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, propsObj.build());
-        }
-    }
-
-    protected void writeExtensions(final JsonObjectBuilder ob,
-            final List<Extension> extensions,
-            final Configurations allConfigs) {
-        for(final Extension ext : extensions) {
-            final String key = ext.getName() + ":" + ext.getType().name() + "|" + ext.isOptional();
-            if ( ext.getType() == ExtensionType.JSON ) {
-                final JsonStructure struct;
-                try ( final StringReader reader = new StringReader(ext.getJSON()) ) {
-                    struct = Json.createReader(reader).read();
-                }
-                ob.add(key, struct);
-            } else if ( ext.getType() == ExtensionType.TEXT ) {
-                ob.add(key, ext.getText());
-            } else {
-                JsonArrayBuilder extensionArr = Json.createArrayBuilder();
-                for(final Artifact artifact : ext.getArtifacts()) {
-                    final Configurations artifactCfgs = new Configurations();
-                    for(final Configuration cfg : allConfigs) {
-                        final String artifactProp = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
-                        if (  artifact.getId().toMvnId().equals(artifactProp) ) {
-                            artifactCfgs.add(cfg);
-                        }
-                    }
-                    if ( artifact.getMetadata().isEmpty() && artifactCfgs.isEmpty() ) {
-                        extensionArr.add(artifact.getId().toMvnId());
-                    } else {
-                        JsonObjectBuilder extObj = Json.createObjectBuilder();
-                        extObj.add(JSONConstants.ARTIFACT_ID, artifact.getId().toMvnId());
-
-                        for(final Map.Entry<String, String> me : artifact.getMetadata()) {
-                            extObj.add(me.getKey(), me.getValue());
-                        }
-
-                        writeConfigurations(ob, artifactCfgs);
-                        extensionArr.add(extObj.build());
-                    }
-                }
-                ob.add(key, extensionArr.build());
-            }
-        }
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
deleted file mode 100644
index ee6585f..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/ManifestUtils.java
+++ /dev/null
@@ -1,515 +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.io.json;
-
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.resource.Capability;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-// This class can be picked up from Felix Utils once it has been moved there. At that point
-// this class can be removed.
-class ManifestUtils {
-    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 {
-            convertProvideCapabilities(
-                    normalizeCapabilityClauses(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);
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    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";
-        }
-    }
-
-    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 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;
-    }
-
-    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;
-    }
-
-    /**
-     * 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;
-    }
-
-    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;
-        }
-    }
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java
deleted file mode 100644
index 6b84931..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/json/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io.json;
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java
deleted file mode 100644
index 25e2f46..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io;
-
-
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java
deleted file mode 100644
index 5f250d7..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProvider.java
+++ /dev/null
@@ -1,55 +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.io.spi;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * The artifact provider is an extension point for providing artifacts
- * from different sources, like for example s3.
- */
-public interface ArtifactProvider {
-
-    /**
-     * The protocol name of the provider, e.g. "s3"
-     * @return The protocol name.
-     */
-    String getProtocol();
-
-    /**
-     * Initialize the provider.
-     * @param context The context
-     * @throws IOException If the provider can't be initialized.
-     */
-    void init(ArtifactProviderContext context) throws IOException;
-
-    /**
-     * Shutdown the provider.
-     */
-    void shutdown();
-
-    /**
-     * Get a local file for the artifact URL.
-     *
-     * @param url Artifact url
-     * @param relativeCachePath A relative path that can be used as a cache path
-     *                          by the provider. The path does not start with a slash.
-     * @return A file if the artifact exists or {@code null}
-     */
-    File getArtifact(String url, String relativeCachePath);
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java
deleted file mode 100644
index c837548..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/ArtifactProviderContext.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.feature.io.spi;
-
-import java.io.File;
-
-/**
- * This is the context for the artifact providers
- */
-public interface ArtifactProviderContext {
-
-    /**
-     * Get the cache directory
-     * @return The cache directory.
-     */
-    File getCacheDirectory();
-
-    /**
-     * Inform about an artifact found in the cache.
-     */
-    void incCachedArtifacts();
-
-    /**
-     * Inform about an artifact being downloaded
-     */
-    void incDownloadedArtifacts();
-
-    /**
-     * Inform about an artifact found locally.
-     */
-    void incLocalArtifacts();
-}
diff --git a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java b/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java
deleted file mode 100644
index b69692b..0000000
--- a/featuremodel/feature-io/src/main/java/org/apache/sling/feature/io/spi/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.io.spi;
-
-
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
deleted file mode 100644
index f89c40b..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
+++ /dev/null
@@ -1,102 +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.io;
-
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ArtifactManagerTest {
-
-    private static final String METADATA = "<metadata modelVersion=\"1.1.0\">\n" +
-            "<groupId>org.apache.sling.samples</groupId>\n" +
-            "<artifactId>slingshot</artifactId>\n" +
-            "<version>0-DEFAULT-SNAPSHOT</version>\n" +
-            "<versioning>\n" +
-                "<snapshot>\n" +
-                    "<timestamp>20160321.103951</timestamp>\n" +
-                    "<buildNumber>1</buildNumber>\n" +
-                "</snapshot>\n" +
-                "<lastUpdated>20160321103951</lastUpdated>\n" +
-                "<snapshotVersions>\n" +
-                    "<snapshotVersion>\n" +
-                        "<extension>txt</extension>\n" +
-                        "<value>0-DEFAULT-20160321.103951-1</value>\n" +
-                        "<updated>20160321103951</updated>\n" +
-                    "</snapshotVersion>\n" +
-                    "<snapshotVersion>\n" +
-                        "<extension>pom</extension>\n" +
-                        "<value>0-DEFAULT-20160321.103951-1</value>\n" +
-                        "<updated>20160321103951</updated>\n" +
-                    "</snapshotVersion>\n" +
-                "</snapshotVersions>\n" +
-            "</versioning></metadata>";
-
-    @Test public void testMetadataParsing() {
-        final String version = ArtifactManager.getLatestSnapshot(METADATA);
-        assertEquals("20160321.103951-1", version);
-    }
-
-    @Test public void testSnapshotHandling() throws IOException {
-        final String REPO = "http://org.apache.sling";
-        final ArtifactManagerConfig config = mock(ArtifactManagerConfig.class);
-        when(config.getRepositoryUrls()).thenReturn(new String[] {REPO});
-
-        final File metadataFile = mock(File.class);
-        when(metadataFile.exists()).thenReturn(true);
-        when(metadataFile.getPath()).thenReturn("/maven-metadata.xml");
-
-        final File artifactFile = mock(File.class);
-        when(artifactFile.exists()).thenReturn(true);
-
-        final ArtifactProvider provider = mock(ArtifactProvider.class);
-        when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(null);
-        when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml", "org.apache.sling/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml")).thenReturn(metadataFile);
-        when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-20160321.103951-1.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(artifactFile);
-
-        final Map<String, ArtifactProvider> providers = new HashMap<>();
-        providers.put("*", provider);
-
-        final ArtifactManager mgr = new ArtifactManager(config, providers) {
-
-            @Override
-            protected String getFileContents(final ArtifactHandler handler) throws IOException {
-                final String path = handler.getFile().getPath();
-                if ( "/maven-metadata.xml".equals(path) ) {
-                    return METADATA;
-                }
-                return super.getFileContents(handler);
-            }
-        };
-
-        final ArtifactHandler handler = mgr.getArtifactHandler("mvn:group/artifact/1.0.0-SNAPSHOT/txt");
-        assertNotNull(handler);
-        assertEquals(artifactFile, handler.getFile());
-    }
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
deleted file mode 100644
index 08ce172..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/IOUtilsTest.java
+++ /dev/null
@@ -1,50 +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.io;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.sling.feature.io.IOUtils;
-import org.junit.Test;
-
-public class IOUtilsTest {
-
-    @Test public void testFileSort() {
-        final String[] files = new String[] {
-            "/different/path/app.json",
-            "/path/to/base.json",
-            "/path/to/feature.json",
-            "/path/to/amode/feature.json",
-            "/path/to/later/feature.json",
-            "http://sling.apache.org/features/one.json",
-            "http://sling.apache.org/features/two.json",
-            "http://sling.apache.org/features/amode/feature.json"
-        };
-
-        final List<String> l = new ArrayList<>(Arrays.asList(files));
-        Collections.sort(l, IOUtils.FEATURE_PATH_COMP);
-        for(int i=0; i<files.length; i++) {
-            assertEquals(files[i], l.get(i));
-        }
-    }
-
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java
deleted file mode 100644
index 47ab83b..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONReaderTest.java
+++ /dev/null
@@ -1,222 +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.io.json;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Extensions;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.apache.sling.feature.KeyValueMap;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.junit.Test;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class FeatureJSONReaderTest {
-
-    @Test public void testRead() throws Exception {
-        final Feature feature = U.readFeature("test");
-        assertNotNull(feature);
-        assertNotNull(feature.getId());
-        assertEquals("org.apache.sling", feature.getId().getGroupId());
-        assertEquals("test-feature", feature.getId().getArtifactId());
-        assertEquals("1.1", feature.getId().getVersion());
-        assertEquals("jar", feature.getId().getType());
-        assertNull(feature.getId().getClassifier());
-
-        assertEquals(2, feature.getConfigurations().size());
-        final Configuration cfg1 = U.findConfiguration(feature.getConfigurations(), "my.pid");
-        assertEquals(7, cfg1.getProperties().get("number"));
-        final Configuration cfg2 = U.findFactoryConfiguration(feature.getConfigurations(), "my.factory.pid", "name");
-        assertEquals("yeah", cfg2.getProperties().get("a.value"));
-
-        assertEquals(3, feature.getCapabilities().size());
-        Capability capability = U.findCapability(feature.getCapabilities(),"osgi.service");
-        assertNotNull(capability.getAttributes().get("objectClass"));
-
-        assertEquals(Arrays.asList("org.osgi.service.http.runtime.HttpServiceRuntime"), capability.getAttributes().get("objectClass"));
-
-    }
-
-    @Test public void testReadWithVariablesResolve() throws Exception {
-        final Feature feature = U.readFeature("test2");
-
-        List<Include> includes = feature.getIncludes();
-        assertEquals(1, includes.size());
-        Include include = includes.get(0);
-        assertEquals("org.apache.sling:sling:9", include.getId().toMvnId());
-
-        List<Requirement> reqs = feature.getRequirements();
-        Requirement req = reqs.get(0);
-        assertEquals("osgi.contract", req.getNamespace());
-        assertEquals("(&(osgi.contract=JavaServlet)(&(version>=3.0)(!(version>=4.0))))",
-                req.getDirectives().get("filter"));
-
-        List<Capability> caps = feature.getCapabilities();
-        Capability cap = null;
-        for (Capability c : caps) {
-            if ("osgi.service".equals(c.getNamespace())) {
-                cap = c;
-                break;
-            }
-        }
-        assertEquals(Collections.singletonList("org.osgi.service.http.runtime.HttpServiceRuntime"),
-                cap.getAttributes().get("objectClass"));
-        assertEquals("org.osgi.service.http.runtime",
-                cap.getDirectives().get("uses"));
-        // TODO this seems quite broken: fix!
-        // assertEquals("org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto",
-        //        cap.getDirectives().get("uses"));
-
-        KeyValueMap fwProps = feature.getFrameworkProperties();
-        assertEquals("Framework property substitution should not happen at resolve time",
-                "${something}", fwProps.get("brave"));
-
-        Bundles bundles = feature.getBundles();
-        ArtifactId id = new ArtifactId("org.apache.sling", "foo-xyz", "1.2.3", null, null);
-        assertTrue(bundles.containsExact(id));
-        ArtifactId id2 = new ArtifactId("org.apache.sling", "bar-xyz", "1.2.3", null, null);
-        assertTrue(bundles.containsExact(id2));
-
-        Configurations configurations = feature.getConfigurations();
-        Configuration config = configurations.getConfiguration("my.pid2");
-        Dictionary<String, Object> props = config.getProperties();
-        assertEquals("Configuration substitution should not happen at resolve time",
-                "aa${ab_config}", props.get("a.value"));
-        assertEquals("${ab_config}bb", props.get("b.value"));
-        assertEquals("c${c_config}c", props.get("c.value"));
-    }
-
-    @Test public void testReadWithVariablesLaunch() throws Exception {
-        final Feature feature = U.readFeature("test3", SubstituteVariables.LAUNCH);
-
-        List<Include> includes = feature.getIncludes();
-        assertEquals(1, includes.size());
-        Include include = includes.get(0);
-        assertEquals("Include substitution should not happen at launch time",
-                "${sling.gid}:sling:10", include.getId().toMvnId());
-
-        List<Requirement> reqs = feature.getRequirements();
-        Requirement req = reqs.get(0);
-        assertEquals("Requirement substitution should not happen at launch time",
-                "osgi.${ns}", req.getNamespace());
-        assertEquals("Requirement substitution should not happen at launch time",
-                "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))",
-                req.getDirectives().get("filter"));
-        assertEquals("There should be 1 directive, comments should be ignored",
-                1, req.getDirectives().size());
-
-        List<Capability> caps = feature.getCapabilities();
-        Capability cap = null;
-        for (Capability c : caps) {
-            if ("osgi.${svc}".equals(c.getNamespace())) {
-                cap = c;
-                break;
-            }
-        }
-        assertEquals("Capability substitution should not happen at launch time",
-                Collections.singletonList("org.osgi.${svc}.http.runtime.HttpServiceRuntime"),
-                cap.getAttributes().get("objectClass"));
-        assertEquals("There should be 1 attribute, comments should be ignored",
-                1, cap.getAttributes().size());
-
-        KeyValueMap fwProps = feature.getFrameworkProperties();
-        assertEquals("something", fwProps.get("brave"));
-        assertEquals("There should be 3 framework properties, comments not included",
-                3, fwProps.size());
-
-        Configurations configurations = feature.getConfigurations();
-        assertEquals("There should be 2 configurations, comments not included",
-                2, configurations.size());
-
-        Configuration config1 = configurations.getConfiguration("my.pid2");
-        for (Enumeration<?> en = config1.getProperties().elements(); en.hasMoreElements(); ) {
-            assertFalse("The comment should not show up in the configuration",
-                "comment".equals(en.nextElement()));
-        }
-
-        Configuration config2 = configurations.getConfiguration("my.pid2");
-        Dictionary<String, Object> props = config2.getProperties();
-        assertEquals("aaright!", props.get("a.value"));
-        assertEquals("right!bb", props.get("b.value"));
-        assertEquals("creally?c", props.get("c.value"));
-        assertEquals("The variable definition looks like a variable definition, this escaping mechanism should work",
-                "${refvar}", props.get("refvar"));
-    }
-
-    @Test public void testReadRepoInitExtension() throws Exception {
-        Feature feature = U.readFeature("repoinit");
-        Extensions extensions = feature.getExtensions();
-        assertEquals(1, extensions.size());
-        Extension ext = extensions.iterator().next();
-        assertEquals("some repo init\ntext", ext.getText());
-    }
-
-    @Test public void testReadRepoInitExtensionArray() throws Exception {
-        Feature feature = U.readFeature("repoinit2");
-        Extensions extensions = feature.getExtensions();
-        assertEquals(1, extensions.size());
-        Extension ext = extensions.iterator().next();
-        assertEquals("some repo init\ntext\n", ext.getText());
-    }
-
-    @Test public void testHandleVars() throws Exception {
-        FeatureJSONReader reader = new FeatureJSONReader(null, null, SubstituteVariables.LAUNCH);
-        Map<String, Object> vars = new HashMap<>();
-        vars.put("var1", "bar");
-        vars.put("varvariable", "${myvar}");
-        vars.put("var.2", "2");
-        setPrivateField(reader, "variables", vars);
-
-        assertEquals("foobarfoo", reader.handleLaunchVars("foo${var1}foo"));
-        assertEquals("barbarbar", reader.handleLaunchVars("${var1}${var1}${var1}"));
-        assertEquals("${}test${myvar}2", reader.handleLaunchVars("${}test${varvariable}${var.2}"));
-        try {
-            reader.handleLaunchVars("${undefined}");
-            fail("Should throw an exception on the undefined variable");
-        } catch (IllegalStateException ise) {
-            // good
-        }
-    }
-
-    private void setPrivateField(Object obj, String name, Object value) throws Exception {
-        Field field = obj.getClass().getDeclaredField(name);
-        field.setAccessible(true);
-        field.set(obj, value);
-    }
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
deleted file mode 100644
index 81db5e6..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/FeatureJSONWriterTest.java
+++ /dev/null
@@ -1,50 +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.io.json;
-
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONWriter;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.junit.Test;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Arrays;
-
-import static org.junit.Assert.assertEquals;
-
-public class FeatureJSONWriterTest {
-
-    @Test public void testRead() throws Exception {
-        final Feature f = U.readFeature("test");
-        final Feature rf;
-        try ( final StringWriter writer = new StringWriter() ) {
-            FeatureJSONWriter.write(writer, f);
-            try ( final StringReader reader = new StringReader(writer.toString()) ) {
-                rf = FeatureJSONReader.read(reader, null, SubstituteVariables.RESOLVE);
-            }
-        }
-        assertEquals(f.getId(), rf.getId());
-        assertEquals("org.apache.sling:test-feature:1.1", rf.getId().toMvnId());
-        assertEquals("The feature description", rf.getDescription());
-
-        assertEquals(Arrays.asList("org.osgi.service.http.runtime.HttpServiceRuntime"),
-                U.findCapability(rf.getCapabilities(), "osgi.service").getAttributes().get("objectClass"));
-    }
-
-}
diff --git a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java b/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java
deleted file mode 100644
index 904f158..0000000
--- a/featuremodel/feature-io/src/test/java/org/apache/sling/feature/io/json/U.java
+++ /dev/null
@@ -1,89 +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.io.json;
-
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.io.json.FeatureJSONReader;
-import org.apache.sling.feature.io.json.FeatureJSONReader.SubstituteVariables;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.List;
-
-import static org.junit.Assert.fail;
-
-/** Test utilities */
-public class U {
-
-    /** Read the feature from the provided resource
-     */
-    public static Feature readFeature(final String name) throws Exception {
-        return readFeature(name, SubstituteVariables.RESOLVE);
-    }
-
-    public static Feature readFeature(final String name, final SubstituteVariables phase) throws Exception {
-        try ( final Reader reader = new InputStreamReader(U.class.getResourceAsStream("/features/" + name + ".json"),
-                "UTF-8") ) {
-            return FeatureJSONReader.read(reader, name, phase);
-        }
-    }
-
-    public static Configuration findConfiguration(final List<Configuration> cfgs, final String pid) {
-        for(final Configuration c : cfgs) {
-            if ( !c.isFactoryConfiguration() && pid.equals(c.getPid()) ) {
-                return c;
-            }
-        }
-        fail("Configuration not found " + pid);
-        return null;
-    }
-
-    public static Configuration findFactoryConfiguration(final List<Configuration> cfgs, final String factoryid, final String name) {
-        for(final Configuration c : cfgs) {
-            if ( c.isFactoryConfiguration() && factoryid.equals(c.getFactoryPid()) && name.equals(c.getName())) {
-                return c;
-            }
-        }
-        fail("Factory Configuration not found " + factoryid + "~" + name);
-        return null;
-    }
-
-    public static Capability findCapability(List<Capability> capabilities, final String namespace) {
-        for (Capability capability : capabilities) {
-            if (capability.getNamespace().equals(namespace)) {
-                return capability;
-            }
-        }
-
-        fail(String.format("No Capability with namespace '%s' found", namespace));
-        return null;
-    }
-
-    public static Requirement findRequirement(List<Requirement> requirements, final String namespace) {
-        for (Requirement requirement : requirements) {
-            if (requirement.getNamespace().equals(namespace)) {
-                return requirement;
-            }
-        }
-
-        fail(String.format("No Requirement with namespace '%s' found", namespace));
-        return null;
-    }
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/repoinit.json b/featuremodel/feature-io/src/test/resources/features/repoinit.json
deleted file mode 100644
index 2177702..0000000
--- a/featuremodel/feature-io/src/test/resources/features/repoinit.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "id": "test/repoinit/1.0.0",
-    "repoinit:TEXT|false": "some repo init\ntext"
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/repoinit2.json b/featuremodel/feature-io/src/test/resources/features/repoinit2.json
deleted file mode 100644
index beef986..0000000
--- a/featuremodel/feature-io/src/test/resources/features/repoinit2.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "id": "test/repoinit2/1.0.0",
-    "repoinit:TEXT|false": [
-        "some repo init",
-        "text"
-    ]
-}
diff --git a/featuremodel/feature-io/src/test/resources/features/test.json b/featuremodel/feature-io/src/test/resources/features/test.json
deleted file mode 100644
index 8ae346c..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
-    "id" : "org.apache.sling/test-feature/1.1",
-    "description": "The feature description",
-
-    "includes" : [
-         {
-             "id" : "org.apache.sling/sling/9",
-             "removals" : {
-                 "configurations" : [
-                 ],
-                 "bundles" : [
-                 ],
-                 "framework-properties" : [
-                 ]
-             }
-         }
-    ],
-    "requirements" : [
-          {
-              "namespace" : "osgi.contract",
-              "directives" : {
-                  "filter" : "(&(osgi.contract=JavaServlet)(&(version>=3.0)(!(version>=4.0))))"
-              }
-          }
-    ],
-    "capabilities" : [
-        {
-             "namespace" : "osgi.implementation",
-             "attributes" : {
-                   "osgi.implementation" : "osgi.http",
-                   "version:Version" : "1.1"
-             },
-             "directives" : {
-                  "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
-             }
-        },
-        {
-             "namespace" : "osgi.service",
-             "attributes" : {
-                  "objectClass:List<String>" : "org.osgi.service.http.runtime.HttpServiceRuntime"
-             },
-             "directives" : {
-                  "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
-             }
-        },
-        {
-          "namespace" : "osgi.contract",
-          "attributes" : {
-            "osgi.contract" : "JavaServlet",
-            "osgi.implementation" : "osgi.http",
-            "version:Version" : "3.1"
-          },
-          "directives" : {
-            "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
-          }
-        }
-    ],
-    "framework-properties" : {
-        "foo" : 1,
-        "brave" : "something",
-        "org.apache.felix.scr.directory" : "launchpad/scr"
-    },
-    "bundles" :[
-            {
-              "id" : "org.apache.sling/oak-server/1.0.0",
-              "hash" : "4632463464363646436",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/application-bundle/2.0.0",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/another-bundle/2.1.0",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/foo-xyz/1.2.3",
-              "start-order" : 2
-            }
-    ],
-    "configurations" : {
-        "my.pid" : {
-           "foo" : 5,
-           "bar" : "test",
-           "number:Integer" : 7
-        },
-        "my.factory.pid~name" : {
-           "a.value" : "yeah"
-        }
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/src/test/resources/features/test2.json b/featuremodel/feature-io/src/test/resources/features/test2.json
deleted file mode 100644
index 0e5c1c6..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test2.json
+++ /dev/null
@@ -1,107 +0,0 @@
-{
-    "model-version": "1",
-    "id" : "org.apache.sling/test2/1.1",
-
-    "variables": {
-         "common.version": "1.2.3",
-         "contract.name": "JavaServlet",
-         "ab_config": "right!",
-         "c_config": "really?",
-         "includever": "9",
-         "ns": "contract",
-         "sling.gid": "org.apache.sling",
-         "something": "something",
-         "svc": "service"
-    },
-
-    "includes" : [
-         {
-             "id" : "${sling.gid}/sling/${includever}",
-             "removals" : {
-                 "configurations" : [
-                 ],
-                 "bundles" : [
-                 ],
-                 "framework-properties" : [
-                 ]
-             }
-         }
-    ],
-    "requirements" : [
-          {
-              "namespace" : "osgi.${ns}",
-              "directives" : {
-                  "filter" : "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))"
-              }
-          }
-    ],
-    "capabilities" : [
-        {
-             "namespace" : "osgi.implementation",
-             "attributes" : {
-                   "osgi.implementation" : "osgi.http",
-                   "version:Version" : "1.1"
-             },
-             "directives" : {
-                  "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
-             }
-        },
-        {
-             "namespace" : "osgi.${svc}",
-             "attributes" : {
-                  "objectClass:List<String>" : "org.osgi.${svc}.http.runtime.HttpServiceRuntime"
-             },
-             "directives" : {
-                  "uses" : "org.osgi.${svc}.http.runtime,org.osgi.${svc}.http.runtime.dto"
-             }
-        },
-        {
-          "namespace" : "osgi.contract",
-          "attributes" : {
-            "osgi.contract" : "JavaServlet",
-            "osgi.implementation" : "osgi.http",
-            "version:Version" : "3.1"
-          },
-          "directives" : {
-            "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
-          }
-        }
-    ],
-    "framework-properties" : {
-        "foo" : 1,
-        "brave" : "${something}",
-        "org.apache.felix.scr.directory" : "launchpad/scr"
-    },
-    "bundles" :[
-            {
-              "id" : "org.apache.sling/oak-server/1.0.0",
-              "hash" : "4632463464363646436",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/application-bundle/2.0.0",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/another-bundle/2.1.0",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/foo-xyz/${common.version}",
-              "start-order" : 2
-            },
-            "org.apache.sling/bar-xyz/${common.version}"
-    ],
-    "configurations" : {
-        "my.pid" : {
-           "foo" : 5,
-           "bar" : "test",
-           "number:Integer" : 7
-        },
-        "my.pid2" : {
-           "a.value" : "aa${ab_config}",
-           "b.value" : "${ab_config}bb",
-           "c.value" : "c${c_config}c"
-        }
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-io/src/test/resources/features/test3.json b/featuremodel/feature-io/src/test/resources/features/test3.json
deleted file mode 100644
index 630239d..0000000
--- a/featuremodel/feature-io/src/test/resources/features/test3.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
-    "#": "A comment",
-    "# array": ["array", "comment"],
-    "id": "org.apache.sling/test2/1.1",
-
-    "variables": {
-         "common.version": "1.2.3",
-         "contract.name": "JavaServlet",
-         "ab_config": "right!",
-         "c_config": "really?",
-         "includever": "9",
-         "ns": "contract",
-         "sling.gid": "org.apache.sling",
-         "something": "something",
-         "svc": "service",
-         "refvar": "${refvar}"
-    },
-
-    "includes" : [
-         {
-             "#": "comment",
-             "id" : "${sling.gid}/sling/10",
-             "removals" : {
-                 "configurations" : [
-                 ],
-                 "bundles" : [
-                 ],
-                 "#": "comment",
-                 "framework-properties" : [
-                 ]
-             }
-         }
-    ],
-    "requirements" : [
-          {
-              "namespace" : "osgi.${ns}",
-              "#": "comment",
-              "directives" : {
-                  "#": "comment",
-                  "filter" : "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))"
-              }
-          }
-    ],
-    "capabilities" : [
-        {
-             "#": "comment",
-             "namespace" : "osgi.implementation",
-             "attributes" : {
-                   "osgi.implementation" : "osgi.http",
-                   "version:Version" : "1.1"
-             },
-             "directives" : {
-                  "uses" : "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"
-             }
-        },
-        {
-             "namespace" : "osgi.${svc}",
-             "attributes" : {
-                  "#": "comment",
-                  "objectClass:List<String>" : "org.osgi.${svc}.http.runtime.HttpServiceRuntime"
-             },
-             "directives" : {
-                  "uses" : "org.osgi.${svc}.http.runtime,org.osgi.${svc}.http.runtime.dto"
-             }
-        },
-        {
-          "namespace" : "osgi.contract",
-          "attributes" : {
-            "osgi.contract" : "JavaServlet",
-            "osgi.implementation" : "osgi.http",
-            "version:Version" : "3.1"
-          },
-          "directives" : {
-            "uses" : "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"
-          }
-        }
-    ],
-    "framework-properties" : {
-        "# one": "comment",
-        "# two": "comment",
-        "foo" : 1,
-        "brave" : "${something}",
-        "org.apache.felix.scr.directory" : "launchpad/scr"
-    },
-    "bundles" :[
-            {
-              "id" : "org.apache.sling/oak-server/1.0.0",
-              "hash" : "4632463464363646436",
-              "start-order" : 1,
-              "#": "comment"
-            },
-            {
-              "id" : "org.apache.sling/application-bundle/2.0.0",
-              "start-order" : 1
-            },
-            {
-              "id" : "org.apache.sling/another-bundle/2.1.0",
-              "start-order" : 1
-            }
-    ],
-    "configurations" : {
-        "#": "comment",
-        "my.pid" : {
-           "#": "comment",
-           "foo" : 5,
-           "bar" : "test",
-           "number:Integer" : 7
-        },
-        "my.pid2" : {
-           "a.value" : "aa${ab_config}",
-           "b.value" : "${ab_config}bb",
-           "c.value" : "c${c_config}c",
-           "refvar": "${refvar}"
-        }
-    }
-}
\ No newline at end of file
diff --git a/featuremodel/feature-karaf/pom.xml b/featuremodel/feature-karaf/pom.xml
deleted file mode 100644
index 6204869..0000000
--- a/featuremodel/feature-karaf/pom.xml
+++ /dev/null
@@ -1,78 +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.karaf</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-    <packaging>bundle</packaging>
-
-    <name>Apache Sling Feature Karaf</name>
-    <description>
-        A feature describes an OSGi system
-    </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-karaf</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-karaf</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-karaf</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-            </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.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>
-    </dependencies>
-</project>
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java
deleted file mode 100644
index e29e7a9..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/ConfigurationUtil.java
+++ /dev/null
@@ -1,87 +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.karaf;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.Map;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.io.json.ConfigurationJSONWriter;
-import org.osgi.framework.Constants;
-
-
-public class ConfigurationUtil {
-
-    public static final String REQUIRE_CONFIGURATOR_CAPABILITY =
-            "osgi.extender;filter:=\"(&(osgi.extender=osgi.configurator)(version>=1.0)(!(version>=2.0)))\"";
-
-    /**
-     * Create a bundle containing the configurations to be processed the
-     * OSGi configurator
-     *
-     * @param os The output stream. The stream is not closed
-     * @param configurations The list of configurations
-     * @param symbolicName The symbolic name for the generated bundle
-     * @param version The version for the generated bundle
-     * @param additionalAttributes Optional additional attributes for the Manifest.
-     * @throws IOException If something goes wrong
-     */
-    public static void createConfiguratorBundle(final OutputStream os,
-            final Configurations configurations,
-            final String symbolicName,
-            final String version,
-            final Map<String, String> additionalAttributes)
-    throws IOException {
-
-        final Manifest mf = new Manifest();
-        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
-        mf.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
-        mf.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
-        mf.getMainAttributes().putValue(Constants.BUNDLE_VERSION, version);
-        mf.getMainAttributes().putValue(Constants.BUNDLE_VENDOR, "The Apache Software Foundation");
-        mf.getMainAttributes().putValue(Constants.REQUIRE_CAPABILITY, REQUIRE_CONFIGURATOR_CAPABILITY);
-
-        if ( additionalAttributes != null ) {
-            for(final Map.Entry<String, String> entry : additionalAttributes.entrySet()) {
-                if ( Constants.REQUIRE_CAPABILITY.equals(entry.getKey())
-                    && !entry.getValue().contains("osgi.extender=osgi.configurator")) {
-                    mf.getMainAttributes().putValue(entry.getKey(), entry.getValue() + "," + REQUIRE_CONFIGURATOR_CAPABILITY);
-                } else {
-                    mf.getMainAttributes().putValue(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-
-        final JarOutputStream jos = new JarOutputStream(os, mf);
-
-        final ZipEntry ze = new ZipEntry("OSGI-INF/configurator/configurations.json");
-        jos.putNextEntry(ze);
-        final Writer w = new OutputStreamWriter(jos, "UTF-8");
-        ConfigurationJSONWriter.write(w, configurations);
-        w.flush();
-        jos.closeEntry();
-
-        jos.flush();
-        jos.finish();
-    }
-}
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java
deleted file mode 100644
index 6bea0f7..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/KarafFeatureWriter.java
+++ /dev/null
@@ -1,197 +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.karaf;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Configurations;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-
-/**
- * This writer writes out a Karaf feature XML.
- *
- */
-public class KarafFeatureWriter {
-    private static final String REQUIRE_REPOINIT_CAPABILITY =
-            "osgi.implementation;filter:=\"(&(osgi.implementation=org.apache.sling.jcr.repoinit)(version>=1.0)(!(version>=2.0)))\"";
-
-
-    public static void writeKAR(final OutputStream os,
-            final Feature feature,
-            final ArtifactManager artifactManager)
-    throws IOException {
-        // check for repoinit extension
-        final Extension repoinitExt = feature.getExtensions().getByName(FeatureConstants.EXTENSION_NAME_REPOINIT);
-        File configurationBundleFile = null;
-        Artifact configuratorBundle = null;
-        try {
-            final Configurations configs = new Configurations();
-            configs.addAll(feature.getConfigurations());
-            if ( repoinitExt != null ) {
-                final Configuration cfg = new Configuration("org.apache.sling.jcr.repoinit.RepositoryInitializer",
-                        "feature-" + feature.getId().getArtifactId());
-                cfg.getProperties().put("scripts", repoinitExt.getText());
-                configs.add(cfg);
-            }
-            if ( !configs.isEmpty() ) {
-                configurationBundleFile = Files.createTempFile(null, null).toFile();
-
-                try ( final FileOutputStream fos = new FileOutputStream(configurationBundleFile)) {
-                    final Map<String, String> map;
-                    if ( repoinitExt == null ) {
-                        map = null;
-                    } else {
-                        map = Collections.singletonMap("Require-Capability", REQUIRE_REPOINIT_CAPABILITY);
-                    }
-                    ConfigurationUtil.createConfiguratorBundle(os,
-                            configs,
-                            feature.getId().getGroupId() + "." + feature.getId().getArtifactId(),
-                            feature.getId().getOSGiVersion().toString(),
-                            map);
-                    configuratorBundle = new Artifact(new ArtifactId(feature.getId().getGroupId(),
-                            feature.getId().getArtifactId(),
-                            feature.getId().getVersion(), "configurator", null));
-                }
-            }
-
-            try ( final ZipOutputStream jos = new ZipOutputStream(os) ) {
-                // repository/features.xml
-                // repository/{maven-path-to-bundle}
-                final ZipEntry xmlEntry = new ZipEntry("repository/features.xml");
-                jos.putNextEntry(xmlEntry);
-
-                final Writer writer = new OutputStreamWriter(jos);
-                writeFeaturesXML(writer, feature, configuratorBundle);
-                writer.flush();
-
-                jos.closeEntry();
-
-                for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
-                    for(final Artifact artifact : entry.getValue()) {
-                        final ArtifactHandler handler = artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());
-
-                        addEntry(jos, artifact, handler.getFile());
-                    }
-                }
-
-                if ( configuratorBundle != null ) {
-                    addEntry(jos, configuratorBundle, configurationBundleFile);
-                }
-            }
-        } finally {
-            if ( configurationBundleFile != null ) {
-                configurationBundleFile.delete();
-            }
-        }
-    }
-
-    private static void addEntry(final ZipOutputStream jos, final Artifact artifact, final File file)
-    throws IOException {
-        final ZipEntry bundleEntry = new ZipEntry("repository/" + artifact.getId().toMvnPath());
-        jos.putNextEntry(bundleEntry);
-
-        final byte[] buffer = new byte[16384];
-        try ( final FileInputStream fis = new FileInputStream(file)) {
-            int l = 0;
-            while ( (l = fis.read(buffer)) > 0 ) {
-                jos.write(buffer, 0, l);
-            }
-        }
-
-        jos.closeEntry();
-    }
-
-    /**
-     * Writes the feature XML to the writer.
-     * The writer is not closed.
-     * @param writer Writer
-     * @param model Model
-     * @throws IOException
-     */
-    private static void writeFeaturesXML(final Writer writer,
-            final Feature feature,
-            final Artifact configuratorBundle)
-    throws IOException {
-        final PrintWriter w = new PrintWriter(writer);
-
-        w.print("<features name=\"");
-        w.print(feature.getId().getArtifactId());
-        w.print("-repo-");
-        w.print(feature.getId().getVersion());
-        w.println("\" xmlns=\"http://karaf.apache.org/xmlns/features/v1.4.0\">");
-
-        write(w, feature, configuratorBundle);
-
-        w.println("</features>");
-        w.flush();
-    }
-
-    private static void write(final PrintWriter w, final Feature feature, final Artifact configuratorBundle)
-    throws IOException {
-        w.print("  <feature name=\"");
-        w.print(feature.getId().getGroupId());
-        w.print('.');
-        w.print(feature.getId().getArtifactId());
-        if ( feature.getId().getClassifier() != null ) {
-            w.print('.');
-            w.print(feature.getId().getClassifier());
-        }
-        w.print("\" version=\"");
-        w.print(feature.getId().getVersion());
-        w.println("\">");
-
-        if ( configuratorBundle != null ) {
-            w.print("     <bundle start-level=\"1\">");
-            w.print(configuratorBundle.getId().toMvnUrl());
-            w.println("</bundle>");
-        }
-
-        // bundles
-        for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
-            for(final Artifact artifact : entry.getValue()) {
-                w.print("     <bundle start-level=\"");
-                w.print(entry.getKey().toString());
-                w.print("\">");
-                w.print(artifact.getId().toMvnUrl());
-                w.println("</bundle>");
-            }
-        }
-
-        w.println("  </feature>");
-    }
-}
diff --git a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java b/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java
deleted file mode 100644
index 76136a3..0000000
--- a/featuremodel/feature-karaf/src/main/java/org/apache/sling/feature/karaf/package-info.java
+++ /dev/null
@@ -1,23 +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.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.karaf;
-
-
diff --git a/featuremodel/feature-launcher/pom.xml b/featuremodel/feature-launcher/pom.xml
deleted file mode 100644
index fdcd201..0000000
--- a/featuremodel/feature-launcher/pom.xml
+++ /dev/null
@@ -1,140 +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.launcher</artifactId>
-    <version>0.0.1-SNAPSHOT</version>
-
-    <name>Apache Sling Feature Launcher</name>
-    <description>
-        A application launcher using Apache Sling Features
-    </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-launcher</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/tooling/support/feature-launcher</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/tooling/support/feature-launcher</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                <execution>
-                    <id>unpack-dependencies</id>
-                    <phase>prepare-package</phase>
-                    <goals>
-                        <goal>unpack-dependencies</goal>
-                    </goals>
-                    <configuration>
-                        <excludes>META-INF/**</excludes>
-                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
-                        <overWriteReleases>false</overWriteReleases>
-                        <overWriteSnapshots>true</overWriteSnapshots>
-                        <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>
-            </plugin>
-                <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifest>
-                            <mainClass>org.apache.sling.feature.launcher.impl.Main</mainClass>
-                        </manifest>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <dependencies>
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>2.6</version>
-        </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.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.io</artifactId>
-            <version>0.0.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.feature.resolver</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>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-             <groupId>commons-cli</groupId>
-             <artifactId>commons-cli</artifactId>
-             <version>1.3.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.johnzon</artifactId>
-            <version>1.0.0</version>
-        </dependency>
-        <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>
-    </dependencies>
-</project>
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
deleted file mode 100644
index 557ec90..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
+++ /dev/null
@@ -1,147 +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.launcher.impl;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.ExtensionType;
-import org.apache.sling.feature.FeatureConstants;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.json.ApplicationJSONReader;
-import org.apache.sling.feature.io.json.ApplicationJSONWriter;
-import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
-import org.apache.sling.feature.resolver.ApplicationResolverAssembler;
-import org.apache.sling.feature.resolver.FeatureResolver;
-import org.apache.sling.feature.resolver.FrameworkResolver;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class FeatureProcessor {
-
-    /**
-     * Initialize the launcher
-     * Read the features and prepare the application
-     * @param config The current configuration
-     * @param artifactManager The artifact manager
-     */
-    public static Application createApplication(final LauncherConfig config,
-            final ArtifactManager artifactManager)
-    throws IOException {
-        Application app = null;
-        if ( config.getApplicationFile() != null ) {
-            String absoluteArg = config.getApplicationFile();
-            if ( absoluteArg.indexOf(":") < 2 ) {
-                absoluteArg = new File(absoluteArg).getAbsolutePath();
-            }
-            final ArtifactHandler appArtifact = artifactManager.getArtifactHandler(absoluteArg);
-
-            try (final FileReader r = new FileReader(appArtifact.getFile())) {
-                app = ApplicationJSONReader.read(r);
-            }
-
-        } else {
-            try (FeatureResolver resolver = new FrameworkResolver(artifactManager, Collections.emptyMap())) {
-                app = ApplicationResolverAssembler.assembleApplication(null, artifactManager, resolver,
-                       org.apache.sling.feature.io.IOUtils.getFeatureFiles(config.getHomeDirectory(), config.getFeatureFiles()).toArray(new String[0]));
-            } catch (Exception ex) {
-                Main.LOG().error("Error while assembling application: {}", ex.getMessage(), ex);
-                System.exit(1);
-            }
-        }
-
-        // write application back
-        final File file = new File(config.getHomeDirectory(), "resources" + File.separatorChar + "provisioning" + File.separatorChar + "application.json");
-        file.getParentFile().mkdirs();
-
-        try (final FileWriter writer = new FileWriter(file)) {
-            ApplicationJSONWriter.write(writer, app);
-        } catch ( final IOException ioe) {
-            Main.LOG().error("Error while writing application file: {}", ioe.getMessage(), ioe);
-            System.exit(1);
-        }
-
-        return app;
-    }
-
-    /**
-     * Prepare the launcher
-     * - add all bundles to the bundle map of the installation object
-     * - add all other artifacts to the install directory (only if startup mode is INSTALL)
-     * - process configurations
-     */
-    public static void prepareLauncher(final LauncherConfig config,
-            final ArtifactManager artifactManager,
-            final Application app) throws Exception {
-        for(final Map.Entry<Integer, List<Artifact>> entry : app.getBundles().getBundlesByStartOrder().entrySet()) {
-            for(final Artifact a : entry.getValue()) {
-                final ArtifactHandler handler = artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
-                final File artifactFile = handler.getFile();
-
-                config.getInstallation().addBundle(entry.getKey(), artifactFile);
-            }
-        }
-        int index = 1;
-        for(final Extension ext : app.getExtensions()) {
-            if ( ext.getType() == ExtensionType.ARTIFACTS ) {
-                for(final Artifact a : ext.getArtifacts() ) {
-                    if ( config.getStartupMode() == StartupMode.PURE ) {
-                        throw new Exception("Artifacts other than bundle are not supported by framework launcher.");
-                    }
-                    final ArtifactHandler handler = artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
-                    config.getInstallation().addInstallableArtifact(handler.getFile());
-                }
-            } else {
-                if ( ext.getName().equals(FeatureConstants.EXTENSION_NAME_REPOINIT) ) {
-                    if ( ext.getType() != ExtensionType.TEXT ) {
-                        throw new Exception(FeatureConstants.EXTENSION_NAME_REPOINIT + " extension must be of type text and not json");
-                    }
-                    final Configuration cfg = new Configuration("org.apache.sling.jcr.repoinit.RepositoryInitializer", "repoinit" + String.valueOf(index));
-                    index++;
-                    cfg.getProperties().put("scripts", ext.getText());
-                    config.getInstallation().addConfiguration(cfg.getName(), cfg.getFactoryPid(), cfg.getProperties());
-                } else {
-                    if ( ext.isRequired() ) {
-                        throw new Exception("Unknown required extension " + ext.getName());
-                    }
-                }
-            }
-        }
-
-        for(final Configuration cfg : app.getConfigurations()) {
-            if ( cfg.isFactoryConfiguration() ) {
-                config.getInstallation().addConfiguration(cfg.getName(), cfg.getFactoryPid(), cfg.getProperties());
-            } else {
-                config.getInstallation().addConfiguration(cfg.getPid(), null, cfg.getProperties());
-            }
-        }
-
-        for(final Map.Entry<String, String> prop : app.getFrameworkProperties()) {
-            if ( !config.getInstallation().getFrameworkProperties().containsKey(prop.getKey()) ) {
-                config.getInstallation().getFrameworkProperties().put(prop.getKey(), prop.getValue());
-            }
-        }
-    }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
deleted file mode 100644
index 2dff508..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
+++ /dev/null
@@ -1,137 +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.launcher.impl;
-
-import org.apache.sling.feature.launcher.spi.LauncherRunContext;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class holds the configuration of the launcher.
- */
-public class Installation implements LauncherRunContext {
-
-    /** The map with the framework properties. */
-    private final Map<String, String> fwkProperties = new HashMap<>();
-
-    /** Bundle map */
-    private final Map<Integer, List<File>> bundleMap = new HashMap<>();
-
-    /** Artifacts to be installed */
-    private final List<File> installables = new ArrayList<>();
-
-    /** Configurations, they are installed on first start. */
-    private final List<Object[]> configurations = new ArrayList<>();
-
-    /** The list of app jars. */
-    private final List<File> appJars = new ArrayList<>();
-
-    /**
-     * Add an application jar.
-     * @param jar The application jar
-     */
-    public void addAppJar(final File jar) {
-        this.appJars.add(jar);
-    }
-
-    /**
-     * Get the list of application jars.
-     * @return The list of app jars
-     */
-    public List<File> getAppJars() {
-        return this.appJars;
-    }
-
-    /**
-     * Add a bundle with the given start level
-     * @param startLevel The start level
-     * @param file The bundle file
-     */
-    public void addBundle(final Integer startLevel, final File file) {
-        List<File> files = bundleMap.get(startLevel);
-        if ( files == null ) {
-            files = new ArrayList<>();
-            bundleMap.put(startLevel, files);
-        }
-        files.add(file);
-    }
-
-    /**
-     * Add an artifact to be installed by the installer
-     * @param file The file
-     */
-    public void addInstallableArtifact(final File file) {
-        this.installables.add(file);
-    }
-
-    /**
-     * Add a configuration
-     * @param pid The pid
-     * @param factoryPid The factory pid
-     * @param properties The propertis
-     */
-    public void addConfiguration(final String pid, final String factoryPid, final Dictionary<String, Object> properties) {
-        this.configurations.add(new Object[] {pid, factoryPid, properties});
-    }
-
-    /**
-     * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getFrameworkProperties()
-     */
-    @Override
-    public Map<String, String> getFrameworkProperties() {
-        return this.fwkProperties;
-    }
-
-    /**
-     * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getBundleMap()
-     */
-    @Override
-    public Map<Integer, List<File>> getBundleMap() {
-        return this.bundleMap;
-    }
-
-    /**
-     * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getConfigurations()
-     */
-    @Override
-    public List<Object[]> getConfigurations() {
-        return this.configurations;
-    }
-
-    /**
-     * @see org.apache.sling.feature.launcher.spi.LauncherRunContext#getInstallableArtifacts()
-     */
-    @Override
-    public List<File> getInstallableArtifacts() {
-        return this.installables;
-    }
-
-    /**
-     * Clear all in-memory objects
-     */
-    public void clear() {
-        this.configurations.clear();
-        this.fwkProperties.clear();
-        this.bundleMap.clear();
-        this.installables.clear();
-    }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
deleted file mode 100644
index 1feb931..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/LauncherConfig.java
+++ /dev/null
@@ -1,122 +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.launcher.impl;
-
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * This class holds the configuration of the launcher.
- */
-public class LauncherConfig
-    extends ArtifactManagerConfig
-    implements ArtifactProviderContext {
-
-    public enum StartupMode {
-        INSTALLER,
-        PURE
-    };
-
-    private static final String HOME = "launcher";
-
-    private static final String CACHE_DIR = "cache";
-
-    /** The feature files or directories. */
-    private volatile String[] featureFiles;
-
-    /** The application file. */
-    private volatile String appFile;
-
-    private volatile StartupMode startupMode = StartupMode.PURE;
-
-    private final Installation installation = new Installation();
-
-    /**
-     * Create a new configuration object.
-     * Set the default values
-     */
-    public LauncherConfig() {
-        this.setCacheDirectory(new File(getHomeDirectory(), CACHE_DIR));
-    }
-
-    public void setApplicationFile(final String value) {
-        appFile = value;
-    }
-
-    public String getApplicationFile() {
-        return this.appFile;
-    }
-
-    /**
-     * Set the list of feature files or directories.
-     * @param value The array with the feature file names.
-     */
-    public void setFeatureFiles(final String[] value) {
-        this.featureFiles = value;
-        if ( value != null && value.length == 0 ) {
-            this.featureFiles = null;
-        }
-    }
-
-    /**
-     * Get the list of feature files.
-     * @return The array of names.
-     * @throws IOException
-     */
-    public String[] getFeatureFiles() {
-        return this.featureFiles;
-    }
-
-
-    /**
-     * Get the home directory.
-     * @return The home directory.
-     */
-    public File getHomeDirectory() {
-        return new File(HOME);
-    }
-
-    /**
-     * Get the startup mode.
-     *
-     * @return The current startup mode.
-     */
-    public StartupMode getStartupMode() {
-        return this.startupMode;
-    }
-
-    /**
-     * Sets the startup mode to {@link StartupMode#INSTALLER}.
-     */
-    public void setUseInstaller() {
-        this.startupMode = StartupMode.INSTALLER;
-    }
-
-    public Installation getInstallation() {
-        return this.installation;
-    }
-
-    /**
-     * Clear all in-memory objects
-     */
-    public void clear() {
-        this.installation.clear();
-    }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
deleted file mode 100644
index 6593319..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
+++ /dev/null
@@ -1,313 +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.launcher.impl;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.launcher.impl.launchers.FrameworkLauncher;
-import org.apache.sling.feature.launcher.spi.Launcher;
-import org.apache.sling.feature.launcher.spi.LauncherPrepareContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is the launcher main class.
- * It parses command line parameters and prepares the launcher.
- */
-public class Main {
-
-    private static Logger LOGGER;
-
-    public static Logger LOG() {
-        if ( LOGGER == null ) {
-            LOGGER = LoggerFactory.getLogger("launcher");
-        }
-        return LOGGER;
-    }
-
-    /** Split a string into key and value */
-    private static String[] split(final String val) {
-        final int pos = val.indexOf('=');
-        if ( pos == -1 ) {
-            return new String[] {val, "true"};
-        }
-        return new String[] {val.substring(0, pos), val.substring(pos + 1)};
-    }
-
-    /**
-     * Parse the command line parameters and update a configuration object.
-     * @param args Command line parameters
-     * @return Configuration object.
-     */
-    private static void parseArgs(final LauncherConfig config, final String[] args) {
-        Main.LOG().info("Assembling configuration...");
-        final Options options = new Options();
-
-        final Option repoOption =  new Option("u", true, "Set repository url");
-        final Option modelOption =  new Option("f", true, "Set feature files/directories");
-        final Option appOption =  new Option("a", true, "Set application file");
-        final Option fwkProperties = new Option("D", true, "Set framework properties");
-        fwkProperties.setArgs(20);
-        final Option debugOption = new Option("v", true, "Verbose");
-        debugOption.setArgs(0);
-        final Option installerOption = new Option("I", true, "Use OSGi installer for additional artifacts.");
-        installerOption.setArgs(0);
-        options.addOption(repoOption);
-        options.addOption(appOption);
-        options.addOption(modelOption);
-        options.addOption(fwkProperties);
-        options.addOption(debugOption);
-        options.addOption(installerOption);
-
-        final CommandLineParser clp = new BasicParser();
-        try {
-            final CommandLine cl = clp.parse(options, args);
-
-            if ( cl.hasOption(repoOption.getOpt()) ) {
-                final String value = cl.getOptionValue(repoOption.getOpt());
-                config.setRepositoryUrls(value.split(","));
-            }
-            if ( cl.hasOption(modelOption.getOpt()) ) {
-                final String value = cl.getOptionValue(modelOption.getOpt());
-                config.setFeatureFiles(value.split(","));
-            }
-            if ( cl.hasOption(fwkProperties.getOpt()) ) {
-                for(final String value : cl.getOptionValues(fwkProperties.getOpt())) {
-                    final String[] keyVal = split(value);
-
-                    config.getInstallation().getFrameworkProperties().put(keyVal[0], keyVal[1]);
-                }
-            }
-            if ( cl.hasOption(debugOption.getOpt()) ) {
-                System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug");
-                LOGGER = null;
-            }
-            if ( cl.hasOption(installerOption.getOpt()) ) {
-                config.setUseInstaller();
-            }
-            if ( cl.hasOption(appOption.getOpt()) ) {
-                config.setApplicationFile(cl.getOptionValue(appOption.getOpt()));
-            }
-        } catch ( final ParseException pe) {
-            Main.LOG().error("Unable to parse command line: {}", pe.getMessage(), pe);
-            System.exit(1);
-        }
-    }
-
-    public static void main(final String[] args) {
-        // setup logging
-        System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
-        System.setProperty("org.slf4j.simpleLogger.showThreadName", "false");
-        System.setProperty("org.slf4j.simpleLogger.levelInBrackets", "true");
-        System.setProperty("org.slf4j.simpleLogger.showLogName", "false");
-        Main.LOG().info("");
-        Main.LOG().info("Apache Sling Application Launcher");
-        Main.LOG().info("---------------------------------");
-
-        // check if launcher has already been created
-        final LauncherConfig launcherConfig = new LauncherConfig();
-        parseArgs(launcherConfig, args);
-
-        ArtifactManager artifactManager = null;
-        try {
-
-            Main.LOG().info("Initializing...");
-            try {
-                artifactManager = ArtifactManager.getArtifactManager(launcherConfig);
-            } catch ( final IOException ioe) {
-                Main.LOG().error("Unable to setup artifact manager: {}", ioe.getMessage(), ioe);
-                System.exit(1);
-            }
-            Main.LOG().info("Artifact Repositories: {}", Arrays.toString(launcherConfig.getRepositoryUrls()));
-            Main.LOG().info("Assembling provisioning model...");
-
-            try {
-                final Launcher launcher = new FrameworkLauncher();
-                final Application app = FeatureProcessor.createApplication(launcherConfig, artifactManager);
-
-                Main.LOG().info("");
-                Main.LOG().info("Assembling launcher...");
-                final ArtifactManager aMgr = artifactManager;
-                final LauncherPrepareContext ctx = new LauncherPrepareContext() {
-
-                    @Override
-                    public File getArtifactFile(final ArtifactId artifact) throws IOException {
-                        final ArtifactHandler handler = aMgr.getArtifactHandler(":" + artifact.toMvnPath());
-                        return handler.getFile();
-                    }
-
-                    @Override
-                    public void addAppJar(final File jar) {
-                        launcherConfig.getInstallation().addAppJar(jar);
-                    }
-                };
-                launcher.prepare(ctx, app);
-
-                FeatureProcessor.prepareLauncher(launcherConfig, artifactManager, app);
-
-            } catch ( final Exception iae) {
-                Main.LOG().error("Error while assembling launcher: {}", iae.getMessage(), iae);
-                System.exit(1);
-            }
-
-            Main.LOG().info("Using {} local artifacts, {} cached artifacts, and {} downloaded artifacts",
-                    launcherConfig.getLocalArtifacts(), launcherConfig.getCachedArtifacts(), launcherConfig.getDownloadedArtifacts());
-        } finally {
-            if ( artifactManager != null ) {
-                artifactManager.shutdown();
-            }
-        }
-
-        try {
-            run(launcherConfig);
-        } catch ( final Exception iae) {
-            Main.LOG().error("Error while running launcher: {}", iae.getMessage(), iae);
-            System.exit(1);
-        }
-    }
-
-    private static final String STORAGE_PROPERTY = "org.osgi.framework.storage";
-
-    private static final String START_LEVEL_PROP = "org.osgi.framework.startlevel.beginning";
-
-    /**
-     * Run launcher.
-     * @param config The configuration
-     * @throws Exception If anything goes wrong
-     */
-    private static void run(final LauncherConfig config) throws Exception {
-        Main.LOG().info("");
-        Main.LOG().info("Starting launcher...");
-        Main.LOG().info("Launcher Home: {}", config.getHomeDirectory().getAbsolutePath());
-        Main.LOG().info("Cache Directory: {}", config.getCacheDirectory().getAbsolutePath());
-        Main.LOG().info("Startup Mode: {}", config.getStartupMode());
-        Main.LOG().info("");
-
-        final Installation installation = config.getInstallation();
-
-        // set sling home, and use separate locations for launchpad and properties
-        installation.getFrameworkProperties().put("sling.home", config.getHomeDirectory().getAbsolutePath());
-        installation.getFrameworkProperties().put("sling.launchpad", config.getHomeDirectory().getAbsolutePath() + "/launchpad");
-        installation.getFrameworkProperties().put("sling.properties", "conf/sling.properties");
-
-
-        // additional OSGi properties
-        // move storage inside launcher
-        if ( installation.getFrameworkProperties().get(STORAGE_PROPERTY) == null ) {
-            installation.getFrameworkProperties().put(STORAGE_PROPERTY, config.getHomeDirectory().getAbsolutePath() + File.separatorChar + "framework");
-        }
-        // set start level to 30
-        if ( installation.getFrameworkProperties().get(START_LEVEL_PROP) == null ) {
-            installation.getFrameworkProperties().put(START_LEVEL_PROP, "30");
-        }
-
-        final Launcher launcher = new FrameworkLauncher();
-        launcher.run(installation, createClassLoader(installation));
-
-        config.clear();
-    }
-
-    /**
-     * Create the class loader.
-     * @param installation The launcher configuration
-     * @throws Exception If anything goes wrong
-     */
-    public static ClassLoader createClassLoader(final Installation installation) throws Exception {
-        final List<URL> list = new ArrayList<>();
-        for(final File f : installation.getAppJars()) {
-            try {
-                list.add(f.toURI().toURL());
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-        list.add(Main.class.getProtectionDomain().getCodeSource().getLocation());
-
-        final URL[] urls = list.toArray(new URL[list.size()]);
-
-        if ( Main.LOG().isDebugEnabled() ) {
-            Main.LOG().debug("App classpath: ");
-            for (int i = 0; i < urls.length; i++) {
-                Main.LOG().debug(" - {}", urls[i]);
-            }
-        }
-
-        // create a paranoid class loader, loading from parent last
-        final ClassLoader cl = new URLClassLoader(urls) {
-            @Override
-            public final Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-                // First check if it's already loaded
-                Class<?> clazz = findLoadedClass(name);
-
-                if (clazz == null) {
-
-                    try {
-                        clazz = findClass(name);
-                    } catch (ClassNotFoundException cnfe) {
-                        ClassLoader parent = getParent();
-                        if (parent != null) {
-                            // Ask to parent ClassLoader (can also throw a CNFE).
-                            clazz = parent.loadClass(name);
-                        } else {
-                            // Propagate exception
-                            throw cnfe;
-                        }
-                    }
-                }
-
-                if (resolve) {
-                    resolveClass(clazz);
-                }
-
-                return clazz;
-            }
-
-            @Override
-            public final URL getResource(final String name) {
-
-                URL resource = findResource(name);
-                ClassLoader parent = this.getParent();
-                if (resource == null && parent != null) {
-                    resource = parent.getResource(name);
-                }
-
-                return resource;
-            }
-        };
-
-        Thread.currentThread().setContextClassLoader(cl);
-
-        return cl;
-    }
-}
diff --git a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java b/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
deleted file mode 100644
index 0be1804..0000000
--- a/featuremodel/feature-launcher/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ /dev/null
@@ -1,278 +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.launcher.impl.launchers;
-
-import org.apache.sling.feature.launcher.impl.Main;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.launch.Framework;
-import org.osgi.framework.startlevel.BundleStartLevel;
-import org.osgi.framework.wiring.FrameworkWiring;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Common functionality for the framework start.
- */
-public class AbstractRunner {
-
-    private volatile ServiceTracker<Object, Object> configAdminTracker;
-
-    private volatile ServiceTracker<Object, Object> installerTracker;
-
-    private final List<Object[]> configurations;
-
-    private final List<File> installables;
-
-    public AbstractRunner(final List<Object[]> configurations, final List<File> installables) {
-        this.configurations = new ArrayList<>(configurations);
-        this.installables = installables;
-    }
-
-    protected void setupFramework(final Framework framework, final Map<Integer, List<File>> bundlesMap)
-    throws BundleException {
-        if ( !configurations.isEmpty() ) {
-            this.configAdminTracker = new ServiceTracker<>(framework.getBundleContext(),
-                    "org.osgi.service.cm.ConfigurationAdmin",
-                    new ServiceTrackerCustomizer<Object, Object>() {
-
-                        @Override
-                        public Object addingService(final ServiceReference<Object> reference) {
-                            // get config admin
-                            final Object cm = framework.getBundleContext().getService(reference);
-                            if ( cm != null ) {
-                                try {
-                                    configure(cm);
-                                } finally {
-                                    framework.getBundleContext().ungetService(reference);
-                                }
-                            }
-                            return null;
-                        }
-
-                        @Override
-                        public void modifiedService(ServiceReference<Object> reference, Object service) {
-                            // nothing to do
-                        }
-
-                        @Override
-                        public void removedService(ServiceReference<Object> reference, Object service) {
-                            // nothing to do
-                        }
-            });
-            this.configAdminTracker.open();
-        }
-        if ( installables != null && !installables.isEmpty() ) {
-            this.installerTracker = new ServiceTracker<>(framework.getBundleContext(),
-                    "org.apache.sling.installer.api.OsgiInstaller",
-                    new ServiceTrackerCustomizer<Object, Object>() {
-
-                        @Override
-                        public Object addingService(final ServiceReference<Object> reference) {
-                            // get installer
-                            final Object installer = framework.getBundleContext().getService(reference);
-                            if ( installer != null ) {
-                                try {
-                                    install(installer);
-                                } finally {
-                                    framework.getBundleContext().ungetService(reference);
-                                }
-                            }
-                            return null;
-                        }
-
-                        @Override
-                        public void modifiedService(ServiceReference<Object> reference, Object service) {
-                            // nothing to do
-                        }
... 11290 lines suppressed ...

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