You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2020/01/07 20:44:33 UTC

[sling-whiteboard] branch master updated: Removed an older project, created both Sling Feature Starter and the Slingstarter Feature Maven Plugin

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

andysch 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 a59ccc7  Removed an older project, created both Sling Feature Starter and the Slingstarter Feature Maven Plugin
a59ccc7 is described below

commit a59ccc778cca844dc276996a7fdc3907f86f6dd8
Author: Andreas Schaefer <sc...@iMac.local>
AuthorDate: Tue Jan 7 12:44:19 2020 -0800

    Removed an older project, created both Sling Feature Starter and the Slingstarter Feature Maven Plugin
---
 .../pom.xml                                        | 259 ------------
 .../src/main/fm/boot_boot.json                     | 114 -----
 .../src/main/fm/composum_composum-nodes.json       |  43 --
 .../src/main/fm/healthcheck_healthcheck.json       | 106 -----
 .../src/main/fm/launchpad_launchpad.json           |  19 -
 .../src/main/fm/oak_oak.json                       | 120 ------
 .../src/main/fm/repoinit_repoinit.json             |  66 ---
 .../src/main/fm/scripting_sling.json               |  96 -----
 .../src/main/fm/sling-caconfig_sling-caconfig.json |  28 --
 .../main/fm/sling-discovery_sling-discovery.json   |  45 --
 .../src/main/fm/sling-event_sling-event.json       |  32 --
 ...els-jacksonexporter_models-jacksonexporter.json |  25 --
 .../main/fm/sling-validation_sling-validation.json |  32 --
 .../src/main/fm/sling_sling.json                   | 450 --------------------
 .../src/main/fm/sling_slingshot.json               |  39 --
 .../src/main/fm/standalone_standalone.json         |  16 -
 .../src/main/fm/webapp_webapp.json                 |   4 -
 sling-org-apache-sling-feature-starter/Readme.md   |  23 +
 sling-org-apache-sling-feature-starter/pom.xml     |  86 +++-
 .../src/main/resources/feature-sling12.json        |   2 +-
 sling-slingstart-feature-maven-plugin/Readme.md    |  51 +++
 sling-slingstart-feature-maven-plugin/pom.xml      | 348 ++++++++++++++++
 .../maven/slingstart/feature/BuildConstants.java   | 105 +++++
 .../slingstart/feature/launcher/Launcher.java      |  96 +++++
 .../slingstart/feature/launcher/LauncherMBean.java |  34 ++
 .../maven/slingstart/feature/launcher/Main.java    | 113 +++++
 .../feature/run/AbstractStartStopMojo.java         |  82 ++++
 .../slingstart/feature/run/ControlListener.java    | 160 +++++++
 .../slingstart/feature/run/LauncherCallable.java   | 369 +++++++++++++++++
 .../feature/run/LaunchpadEnvironment.java          | 152 +++++++
 .../maven/slingstart/feature/run/PortHelper.java   |  49 +++
 .../slingstart/feature/run/ProcessDescription.java |  81 ++++
 .../feature/run/ProcessDescriptionProvider.java    | 106 +++++
 .../feature/run/ServerConfiguration.java           | 219 ++++++++++
 .../maven/slingstart/feature/run/StartMojo.java    | 461 +++++++++++++++++++++
 .../maven/slingstart/feature/run/StopMojo.java     |  88 ++++
 36 files changed, 2617 insertions(+), 1502 deletions(-)

diff --git a/sling-org-apache-sling-feature-model-starter/pom.xml b/sling-org-apache-sling-feature-model-starter/pom.xml
deleted file mode 100644
index 3a4188f..0000000
--- a/sling-org-apache-sling-feature-model-starter/pom.xml
+++ /dev/null
@@ -1,259 +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>35</version>
-        <relativePath />
-    </parent>
-
-    <artifactId>org.apache.sling.feature.model.starter</artifactId>
-    <packaging>slingosgifeature</packaging>
-    <version>12-SNAPSHOT</version>
-
-    <name>Apache Sling Feature Module Starter Application</name>
-    <description>
-        The Sling Starter application built from Feature Models
-    </description>
-
-<!--    <scm>-->
-<!--        <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter.git</connection>-->
-<!--        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter.git</developerConnection>-->
-<!--        <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-starter.git</url>-->
-<!--      <tag>HEAD</tag>-->
-<!--  </scm>-->
-
-    <properties>
-        <sling.java.version>8</sling.java.version>
-        <IT.expected.bundles.count>126</IT.expected.bundles.count>
-        <slingfeature-maven-plugin.version>1.1.10</slingfeature-maven-plugin.version>
-    </properties>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>ianal-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>verify-legal-files</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <artifactId>maven-clean-plugin</artifactId>
-                <configuration>
-                    <filesets>
-                        <fileset>
-                            <directory>${basedir}</directory>
-                            <includes>
-                                <include>derby.log</include>
-                                <include>cachedir/**</include>
-                                <include>sling/**</include>
-                                <include>jackrabbit/**</include>
-                                <include>coverage.ec</include>
-                            </includes>
-                        </fileset>
-                    </filesets>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.sling</groupId>
-                <artifactId>slingfeature-maven-plugin</artifactId>
-                <version>${slingfeature-maven-plugin.version}</version>
-                <extensions>true</extensions>
-                <configuration>
-                    <features>src/main/fm</features>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>aggregate-base-feature</id>
-                        <phase>generate-test-sources</phase>
-                        <goals>
-                            <goal>aggregate-features</goal>
-                        </goals>
-                        <configuration>
-                            <aggregates>
-                                <aggregate>
-                                    <classifier>sling12</classifier>
-                                    <filesInclude>**/*.json</filesInclude>
-                                    <includeArtifact>
-                                        <groupId>org.apache.sling</groupId>
-                                        <artifactId>org.apache.sling.jcr.packageinit</artifactId>
-                                        <version>0.0.1-SNAPSHOT</version>
-<!--                                        <classifier>jcr-packageinit</classifier>-->
-                                        <type>pom</type>
-                                    </includeArtifact>
-                                </aggregate>
-                            </aggregates>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>attach-base-feature</id>
-                        <phase>process-test-sources</phase>
-                        <goals>
-                            <goal>attach-features</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-<!--            <plugin>-->
-<!--                <groupId>org.apache.sling</groupId>-->
-<!--                <artifactId>slingstart-maven-plugin</artifactId>-->
-<!--                <extensions>true</extensions>-->
-<!--                <executions>-->
-<!--                    <execution>-->
-<!--                         <id>start-container</id>-->
-<!--                        <goals>-->
-<!--                            <goal>start</goal>-->
-<!--                            <goal>stop</goal>-->
-<!--                        </goals>-->
-<!--                    </execution>-->
-<!--                </executions>                -->
-<!--                <configuration>-->
-<!--                    <createWebapp>true</createWebapp>-->
-<!--                    <servers>-->
-<!--                        <server>-->
-<!--                            <port>${http.port}</port>-->
-<!--                            <controlPort>${sling.control.port}</controlPort>-->
-<!--                        </server>-->
-<!--                    </servers>                    -->
-<!--                </configuration>-->
-<!--            </plugin>-->
-
-<!--            <plugin>-->
-<!--                <groupId>org.codehaus.mojo</groupId>-->
-<!--                <artifactId>build-helper-maven-plugin</artifactId>-->
-<!--                <executions>-->
-<!--                    <execution>-->
-<!--                        <id>reserve-network-port</id>-->
-<!--                        <goals>-->
-<!--                            &lt;!&ndash; pre-integration-test is too late &ndash;&gt;-->
-<!--                            <goal>reserve-network-port</goal>-->
-<!--                        </goals>-->
-<!--                        <phase>process-resources</phase>-->
-<!--                        <configuration>-->
-<!--                            <portNames>-->
-<!--                                <portName>http.port</portName>-->
-<!--                                <portName>sling.control.port</portName>-->
-<!--                            </portNames>-->
-<!--                        </configuration>-->
-<!--                    </execution>-->
-<!--                </executions>-->
-<!--            </plugin>-->
-
-<!--            <plugin>-->
-<!--                <artifactId>maven-failsafe-plugin</artifactId>-->
-<!--                <executions>-->
-<!--                    <execution>-->
-<!--                        <goals>-->
-<!--                            <goal>integration-test</goal>-->
-<!--                            <goal>verify</goal>-->
-<!--                        </goals>-->
-<!--                    </execution>-->
-<!--                </executions>-->
-<!--                <configuration>-->
-<!--                    <systemPropertyVariables>-->
-<!--                        <launchpad.http.port>${http.port}</launchpad.http.port>-->
-<!--                        <IT.expected.bundles.count>${IT.expected.bundles.count}</IT.expected.bundles.count>-->
-<!--                    </systemPropertyVariables>-->
-<!--                </configuration>-->
-<!--            </plugin>            -->
-        </plugins>
-
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <!-- Extend RAT configuration from parent pom -->
-                    <groupId>org.apache.rat</groupId>
-                    <artifactId>apache-rat-plugin</artifactId>
-                    <configuration>
-                        <excludes combine.children="append">
-                            <!-- Exclude sling instance -->
-                            <exclude>sling/**</exclude>
-                        </excludes>
-                    </configuration>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-
-    </build>
-    
-    <dependencies>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient</artifactId>
-            <version>4.5.6</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.utils</artifactId>
-            <version>1.11.0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <profiles>
-        <profile>
-            <id>launch</id>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.sling</groupId>
-                        <artifactId>slingfeature-maven-plugin</artifactId>
-                        <version>1.0.7-SNAPSHOT</version>
-                        <extensions>true</extensions>
-                        <dependencies>
-                            <dependency>
-                                <groupId>org.apache.sling</groupId>
-                                <artifactId>org.apache.sling.feature.launcher</artifactId>
-                                <version>1.0.7-SNAPSHOT</version>
-                            </dependency>
-                            <dependency>
-                                <groupId>org.apache.sling</groupId>
-                                <artifactId>org.apache.sling.feature.extension.content</artifactId>
-                                <version>1.0.5-SNAPSHOT</version>
-                            </dependency>
-                        </dependencies>
-                        <executions>
-                            <execution>
-                                <id>launch-it</id>
-                                <phase>install</phase>
-                                <goals>
-                                    <goal>launch-features</goal>
-                                </goals>
-                                <configuration>
-                                    <selection>
-                                        <includeClassifier>sling12</includeClassifier>
-                                    </selection>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
-
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json
deleted file mode 100644
index 543c3f0..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/boot_boot.json
+++ /dev/null
@@ -1,114 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:boot:12-SNAPSHOT",
-    "variables":{
-        "slf4j.version":"1.7.25"
-    },
-    "bundles":[
-        {
-            "id":"org.apache.aries:org.apache.aries.util:1.1.3",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.commons:commons-lang3:3.8.1",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.configadmin:1.9.14",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.eventadmin:1.5.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.geronimo.specs:geronimo-annotation_1.3_spec:1.1",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.geronimo.specs:geronimo-atinject_1.0_spec:1.1",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:1.1.3",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.jaxb-impl:2.2.11_1",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.saaj-impl:1.3.23_2",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.jaxb-api-2.2:2.9.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.jaxws-api-2.2:2.9.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.servicemix.specs:org.apache.servicemix.specs.saaj-api-1.3:2.8.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.log:5.1.10",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.logservice:1.0.6",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.core:3.9.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.factory.configuration:1.2.2",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.provider.file:1.1.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.javax.activation:0.1.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.settings:1.3.10",
-            "start-order":"1"
-        },
-        {
-            "id":"org.jvnet.staxex:stax-ex:1.7.6",
-            "start-order":"1"
-        },
-        {
-            "id":"org.osgi:org.osgi.util.function:1.1.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.osgi:org.osgi.util.promise:1.1.0",
-            "start-order":"1"
-        },
-        {
-            "id":"org.slf4j:jcl-over-slf4j:1.7.25",
-            "start-order":"1"
-        },
-        {
-            "id":"org.slf4j:log4j-over-slf4j:1.7.25",
-            "start-order":"1"
-        },
-        {
-            "id":"org.slf4j:slf4j-api:1.7.25",
-            "start-order":"1"
-        }
-    ],
-    "framework-properties":{
-        "sling.run.mode.install.options":"oak_tar,oak_mongo",
-        "localIndexDir":"${sling.home}/repository/index",
-        "repository.home":"${sling.home}/repository"
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json
deleted file mode 100644
index 56297ef..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/composum_composum-nodes.json
+++ /dev/null
@@ -1,43 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:composum_composum-nodes:12-SNAPSHOT",
-    "variables":{
-        "composum.nodes.version":"1.11.3"
-    },
-    "bundles":[
-        {
-            "id":"com.composum.sling.core:composum-sling-core-commons:1.11.3",
-            "start-order":"20"
-        },
-        {
-            "id":"com.composum.sling.core:composum-sling-core-console:1.11.3",
-            "start-order":"20"
-        },
-        {
-            "id":"com.composum.sling.core:composum-sling-core-jslibs:1.11.3",
-            "start-order":"20"
-        },
-        {
-            "id":"com.composum.sling.core:composum-sling-package-manager:1.11.3",
-            "start-order":"20"
-        },
-        {
-            "id":"com.composum.sling.core:composum-sling-user-management:1.11.3",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.jackrabbit.vault:org.apache.jackrabbit.vault:3.2.4",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment~composum":{
-            "whitelist.bundles":[
-                "com.composum.core.commons",
-                "com.composum.core.pckgmgr",
-                "com.composum.core.pckginstall"
-            ],
-            "whitelist.name":"composum"
-        }
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json
deleted file mode 100644
index f83dc3c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/healthcheck_healthcheck.json
+++ /dev/null
@@ -1,106 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:healthcheck:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.felix:org.apache.felix.healthcheck.api:2.0.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.healthcheck.core:2.0.6",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.healthcheck.generalchecks:2.0.4",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.healthcheck.webconsoleplugin:2.0.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.hc.api:1.0.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.hc.support:1.0.6",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.felix.hc.generalchecks.BundlesStartedCheck":{
-            "hc.tags":[
-                "bundles"
-            ]
-        },
-        "org.apache.felix.hc.generalchecks.CpuCheck":{
-            "hc.tags":[
-                "cpu",
-                "system-resources"
-            ],
-            "cpuPercentageThresholdWarn":95
-        },
-        "org.apache.felix.hc.generalchecks.DiskSpaceCheck":{
-            "hc.tags":[
-                "diskspace",
-                "system-resources"
-            ],
-            "diskPaths":[
-                "."
-            ]
-        },
-        "org.apache.felix.hc.generalchecks.FrameworkStartCheck":{
-            "hc.tags":[
-                "systemalive"
-            ],
-            "targetStartLevel:Integer":"30"
-        },
-        "org.apache.felix.hc.generalchecks.MemoryCheck":{
-            "hc.tags":[
-                "memory",
-                "system-resources"
-            ],
-            "heapUsedPercentageThresholdCritical":100,
-            "heapUsedPercentageThresholdWarn":95
-        },
-        "org.apache.felix.hc.generalchecks.ServicesCheck":{
-            "hc.tags":[
-                "systemalive"
-            ],
-            "services.list":[
-                "org.apache.sling.jcr.api.SlingRepository",
-                "org.apache.sling.engine.auth.Authenticator",
-                "org.apache.sling.api.resource.ResourceResolverFactory",
-                "org.apache.sling.api.servlets.ServletResolver",
-                "javax.script.ScriptEngineManager"
-            ]
-        },
-        "org.apache.felix.hc.generalchecks.ThreadUsageCheck":{
-            "hc.tags":[
-                "threads",
-                "cpu",
-                "system-resources"
-            ]
-        },
-        "org.apache.felix.hc.core.impl.filter.ServiceUnavailableFilter~startupandshutdown":{
-            "osgi.http.whiteboard.filter.regex":"(?!/system/).*",
-            "avoid404DuringStartup":true,
-            "service.ranking:Integer":"2147483647",
-            "includeExecutionResult":false,
-            "osgi.http.whiteboard.context.select":"(osgi.http.whiteboard.context.name=*)",
-            "tags":[
-                "systemalive"
-            ],
-            "autoDisableFilter":true,
-            "responseTextFor503":"classpath:org.apache.sling.starter.content:content/content/startup/index.html"
-        },
-        "org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet~default":{
-            "servletPath":"/system/health"
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~hc-support":{
-            "user.mapping":[
-                "org.apache.sling.hc.support=sling-readall"
-            ]
-        }
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json
deleted file mode 100644
index d36c980..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/launchpad_launchpad.json
+++ /dev/null
@@ -1,19 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:launchpad:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.launchpad.base:6.0.2-2.6.36",
-            "start-order":"20"
-        }
-    ],
-    "framework-properties":{
-        "sling.jre.java.xml":",javax.xml;version=\"2.1.0\",javax.xml.datatype;uses:=\"javax.xml.namespace\";version=\"2.1.0\",javax.xml.namespace;version=\"2.1.0\",javax.xml.parsers;uses:=\"javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers\";version=\"2.1.0\",javax.xml.stream;uses:=\"javax.xml.namespace,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform\";version=\"1.0.0\",javax.xml.stream.events;uses:=\"javax.xml.namespace,javax.xml.stream\";version=\"1.0.0 [...]
-        "felix.systempackages.calculate.uses":"true",
-        "org.osgi.framework.system.packages":"org.osgi.framework;version=\"1.9\",org.osgi.framework.dto;version=\"1.8\";uses:=\"org.osgi.dto\",org.osgi.framework.hooks.bundle;version=\"1.1\";uses:=\"org.osgi.framework\",org.osgi.framework.hooks.resolver;version=\"1.0\";uses:=\"org.osgi.framework.wiring\",org.osgi.framework.hooks.service;version=\"1.1\";uses:=\"org.osgi.framework\",org.osgi.framework.hooks.weaving;version=\"1.1\";uses:=\"org.osgi.framework.wiring\",org.osgi.framework.laun [...]
-        "felix.systempackages.substitution":"true",
-        "sling.jre-jpms":"{dollar}{felix.jpms.java.base}{dollar}{felix.jpms.java.compiler}{dollar}{felix.jpms.java.datatransfer}{dollar}{felix.jpms.java.desktop}{dollar}{felix.jpms.java.instrument}{dollar}{felix.jpms.java.logging}{dollar}{felix.jpms.java.management}{dollar}{felix.jpms.java.management.rmi}{dollar}{felix.jpms.java.naming}{dollar}{felix.jpms.java.net.http}{dollar}{felix.jpms.java.prefs}{dollar}{felix.jpms.java.rmi}{dollar}{felix.jpms.java.scripting}{dollar}{felix.jpms.java. [...]
-        "sling.jpms.java.xml":"{dollar}{sling.jre.java.xml},javax.xml.catalog;uses:=\"javax.xml.namespace\";version=\"1.0.0\"",
-        "sling.jre-1.8":",java.applet;version=\"{dollar}{felix.detect.java.version}\",java.awt;version=\"{dollar}{felix.detect.java.version}\",java.awt.color;version=\"{dollar}{felix.detect.java.version}\",java.awt.datatransfer;version=\"{dollar}{felix.detect.java.version}\",java.awt.dnd;version=\"{dollar}{felix.detect.java.version}\",java.awt.event;version=\"{dollar}{felix.detect.java.version}\",java.awt.font;version=\"{dollar}{felix.detect.java.version}\",java.awt.geom;version=\"{dolla [...]
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json
deleted file mode 100644
index 4871cd8..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/oak_oak.json
+++ /dev/null
@@ -1,120 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:oak:12-SNAPSHOT",
-    "variables":{
-        "oak.version":"1.16.0"
-    },
-    "bundles":[
-        {
-            "id":"org.apache.felix:org.apache.felix.jaas:1.0.2",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-api:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-blob-plugins:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-blob:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-commons:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-core-spi:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-core:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-jcr:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-lucene:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-query-spi:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-security-spi:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-store-composite:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-store-document:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-store-spi:1.16.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.oak.server:1.2.2",
-            "start-order":"16"
-        },
-        {
-            "id":"org.apache.jackrabbit:oak-segment-tar:1.16.0",
-            "run-modes":"oak_tar",
-            "start-order":"15"
-        }
-    ],
-    "configurations":{
-        "org.apache.felix.jaas.ConfigurationSpi":{
-            "jaas.defaultRealmName":"jackrabbit.oak",
-            "jaas.configProviderName":"FelixJaasProvider"
-        },
-        "org.apache.jackrabbit.oak.security.authentication.AuthenticationConfigurationImpl":{
-            "org.apache.jackrabbit.oak.authentication.configSpiName":"FelixJaasProvider"
-        },
-        "org.apache.jackrabbit.oak.security.user.RandomAuthorizableNodeName":{
-            "length:Integer":"21"
-        },
-        "org.apache.jackrabbit.oak.security.user.UserConfigurationImpl":{
-            "groupsPath":"/home/groups",
-            "defaultDepth":"1",
-            "importBehavior":"besteffort",
-            "usersPath":"/home/users"
-        },
-        "org.apache.jackrabbit.oak.spi.security.user.action.DefaultAuthorizableActionProvider":{
-            "userPrivilegeNames":[
-                "jcr:all"
-            ],
-            "groupPrivilegeNames":[
-                "jcr:read"
-            ],
-            "enabledActions":[
-                "org.apache.jackrabbit.oak.spi.security.user.action.AccessControlAction"
-            ]
-        },
-        "org.apache.felix.jaas.Configuration.factory~GuestLoginModule":{
-            "jaas.controlFlag":"optional",
-            "jaas.classname":"org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule",
-            "jaas.ranking:Integer":"300"
-        },
-        "org.apache.felix.jaas.Configuration.factory~LoginModuleImpl":{
-            "jaas.controlFlag":"required",
-            "jaas.classname":"org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl"
-        },
-        "org.apache.felix.jaas.Configuration.factory~TokenLoginModule":{
-            "jaas.controlFlag":"sufficient",
-            "jaas.classname":"org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule",
-            "jaas.ranking:Integer":"200"
-        },
-        "org.apache.jackrabbit.oak.segment.SegmentNodeStoreService":{
-            "name":"Default NodeStore"
-        }
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json
deleted file mode 100644
index 2c75958..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/repoinit_repoinit.json
+++ /dev/null
@@ -1,66 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:repoinit:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.repoinit:1.1.10",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.provisioning.model:1.8.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.repoinit.parser:1.2.4",
-            "start-order":"20"
-        }
-    ],
-    "repoinit:TEXT|true":[
-        "# general",
-        "create path (sling:OrderedFolder) /content",
-        "set ACL for everyone",
-        "allow   jcr:read\ton /content",
-        "end",
-        "",
-        "# sling-mapping",
-        "create service user sling-mapping",
-        "",
-        "set ACL for sling-mapping",
-        "allow   jcr:read    on /",
-        "end",
-        "",
-        "# sling-readall",
-        "create service user sling-readall",
-        "",
-        "set ACL for sling-readall",
-        "allow   jcr:read    on /",
-        "end",
-        "",
-        "# sling-xss",
-        "create service user sling-xss",
-        "",
-        "create path (sling:Folder) /apps/sling/xss",
-        "",
-        "set ACL for sling-xss",
-        "allow   jcr:read    on /apps/sling/xss",
-        "end",
-        "",
-        "# sling-i18n",
-        "create service user sling-i18n",
-        "",
-        "set ACL for sling-i18n",
-        "allow   jcr:read    on /",
-        "end",
-        "",
-        "# sling-jcr-install",
-        "create service user sling-jcr-install",
-        "",
-        "# used for config OSGi writeback",
-        "create path (sling:Folder) /apps/sling/install",
-        "",
-        "set ACL for sling-jcr-install",
-        "allow\tjcr:read\ton\t/",
-        "allow\trep:write\ton /apps/sling/install",
-        "end"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json
deleted file mode 100644
index 818dbd6..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/scripting_sling.json
+++ /dev/null
@@ -1,96 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:scripting_sling:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.antlr:antlr4-runtime:4.7.1",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.servicemix.bundles:org.apache.servicemix.bundles.rhino:1.7.10_1",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.api:2.2.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.core:2.0.56",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.el-api:1.0.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.javascript:3.0.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.jsp-api:1.0.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.jsp.taglib:2.4.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.jsp:2.3.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.compiler.java:1.1.2-1.4.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.compiler:1.1.2-1.4.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.js.provider:1.0.28",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.models.provider:1.0.8",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.repl:1.0.6",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly.runtime:1.1.0-1.4.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.scripting.sightly:1.1.2-1.4.0",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.scripting.core.impl.ScriptCacheImpl":{
-            "org.apache.sling.scripting.cache.additional_extensions":[
-                "js"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~scripting":{
-            "user.mapping":[
-                "org.apache.sling.scripting.core=sling-scripting",
-                "org.apache.sling.scripting.sightly.js.provider=sling-scripting"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "#<<< SLING-5848 - Define service user and ACLs for Scripting",
-        "create service user sling-scripting",
-        "",
-        "create path (sling:Folder) /libs",
-        "create path (sling:Folder) /apps",
-        "",
-        "set ACL for sling-scripting",
-        "deny    jcr:all     on /",
-        "allow   jcr:read    on /libs,/apps",
-        "end",
-        "# SLING-5848 - Define service user and ACLs for Scripting >>>"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json
deleted file mode 100644
index cc3131d..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-caconfig_sling-caconfig.json
+++ /dev/null
@@ -1,28 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-caconfig:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.caconfig.api:1.1.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.caconfig.impl:1.4.14",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.caconfig.spi:1.3.4",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling-caconfig":{
-            "user.mapping":[
-                "org.apache.sling.caconfig.impl=sling-readall"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "create path (sling:Folder) /conf"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json
deleted file mode 100644
index c50f992..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-discovery_sling-discovery.json
+++ /dev/null
@@ -1,45 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-discovery:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.discovery.api:1.0.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.discovery.base:2.0.8",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.discovery.commons:1.0.20",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.discovery.oak:1.2.28",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.discovery.support:1.0.4",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.discovery":{
-            "user.mapping":[
-                "org.apache.sling.discovery.commons=sling-discovery",
-                "org.apache.sling.discovery.base=sling-discovery",
-                "org.apache.sling.discovery.oak=sling-discovery"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "create service user sling-discovery",
-        "",
-        "create path (sling:Folder) /var/discovery",
-        "create path (sling:Folder) /var/discovery/oak",
-        "",
-        "set ACL for sling-discovery",
-        "allow   jcr:read,rep:write    on /var/discovery",
-        "end"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json
deleted file mode 100644
index 8cd957e..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-event_sling-event.json
+++ /dev/null
@@ -1,32 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-event:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.event.dea:1.1.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.event:4.2.12",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.event":{
-            "user.mapping":[
-                "org.apache.sling.event=sling-event",
-                "org.apache.sling.event.dea=sling-event"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "create service user sling-event",
-        "",
-        "create path (sling:Folder) /var",
-        "create path (sling:Folder) /var/eventing",
-        "",
-        "set ACL for sling-event",
-        "allow   jcr:read,rep:write    on /var/eventing",
-        "end"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json
deleted file mode 100644
index f2e664c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-models-jacksonexporter_models-jacksonexporter.json
+++ /dev/null
@@ -1,25 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-models-jacksonexporter_models-jacksonexporter:12-SNAPSHOT",
-    "variables":{
-        "jackson.version":"2.9.9"
-    },
-    "bundles":[
-        {
-            "id":"com.fasterxml.jackson.core:jackson-annotations:2.9.9",
-            "start-order":"20"
-        },
-        {
-            "id":"com.fasterxml.jackson.core:jackson-core:2.9.9",
-            "start-order":"20"
-        },
-        {
-            "id":"com.fasterxml.jackson.core:jackson-databind:2.9.9",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.models.jacksonexporter:1.0.8",
-            "start-order":"20"
-        }
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json
deleted file mode 100644
index da06699..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling-validation_sling-validation.json
+++ /dev/null
@@ -1,32 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling-validation:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.validation.api:1.0.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.validation.core:1.0.4",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~validation":{
-            "user.mapping":[
-                "org.apache.sling.validation.core=sling-validation"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "create service user sling-validation",
-        "",
-        "create path (sling:Folder) /apps",
-        "create path (sling:Folder) /libs",
-        "",
-        "set ACL for sling-validation",
-        "allow   jcr:read    on /apps",
-        "allow   jcr:read    on /libs",
-        "end"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json
deleted file mode 100644
index cca427c..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_sling.json
+++ /dev/null
@@ -1,450 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling:12-SNAPSHOT",
-    "variables":{
-        "jackrabbit.version":"2.18.2"
-    },
-    "bundles":[
-        {
-            "id":"commons-codec:commons-codec:1.12",
-            "start-order":"20"
-        },
-        {
-            "id":"commons-collections:commons-collections:3.2.2",
-            "start-order":"20"
-        },
-        {
-            "id":"javax.mail:mail:1.5.0-b01",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.commons:commons-collections4:4.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.commons:commons-math:2.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.geronimo.bundles:jstl:1.2_1",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.httpcomponents:httpclient-osgi:4.5.6",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.httpcomponents:httpcore-osgi:4.4.10",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.adapter:2.1.10",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.auth.form:1.0.14",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.bundleresource.impl:2.3.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.classloader:1.4.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.compiler:2.3.6",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.fsclassloader:1.0.10",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.mime:2.2.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.osgi:2.4.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.scheduler:2.7.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.threads:3.2.18",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.engine:2.6.18",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.fsresource:2.1.14",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.i18n:2.5.14",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.console:1.0.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.hc:2.0.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.installer.provider.jcr:3.1.26",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.contentloader:2.3.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.resource:3.0.18",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.models.api:1.3.8",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.models.impl:1.4.10",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.resourceresolver:1.6.8",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.serviceuser.webconsole:1.0.0",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.serviceusermapper:1.4.4",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.servlets.get:2.1.40",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.servlets.post:2.3.30",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.servlets.resolver:2.5.2",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.xss:2.1.8",
-            "start-order":"20"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.metatype:1.2.2",
-            "start-order":"4"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.scr:2.1.16",
-            "start-order":"4"
-        },
-        {
-            "id":"commons-fileupload:commons-fileupload:1.3.3",
-            "start-order":"5"
-        },
-        {
-            "id":"commons-io:commons-io:2.6",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.aries.jmx:org.apache.aries.jmx.api:1.1.5",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.aries.jmx:org.apache.aries.jmx.core:1.1.8",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.aries.jmx:org.apache.aries.jmx.whiteboard:1.2.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.bundlerepository:2.0.10",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.http.whiteboard:4.0.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.inventory:1.0.6",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.prefs:1.1.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole.plugins.ds:2.1.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole.plugins.event:1.1.8",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole.plugins.memoryusage:1.0.8",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole.plugins.obr:1.0.4",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole.plugins.packageadmin:1.0.4",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.webconsole:4.3.8",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.api:2.20.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.auth.core:1.4.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.johnzon:1.1.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.log.webconsole:1.0.0",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.extensions.threaddump:0.2.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.extensions.webconsolebranding:1.0.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.extensions.webconsolesecurityprovider:1.2.2",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.starter.content:1.0.4",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.http.sslfilter:1.2.6",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.pdfbox:fontbox:2.0.16",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.pdfbox:jempbox:1.8.16",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.pdfbox:pdfbox:2.0.16",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.tika:tika-core:1.21",
-            "start-order":"10"
-        },
-        {
-            "id":"org.apache.tika:tika-parsers:1.21",
-            "start-order":"10"
-        },
-        {
-            "id":"com.google.guava:guava:15.0",
-            "start-order":"15"
-        },
-        {
-            "id":"io.dropwizard.metrics:metrics-core:3.2.6",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-api:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-data:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-jcr-commons:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-jcr-rmi:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-spi-commons:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-spi:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.jackrabbit:jackrabbit-webdav:2.18.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.commons.metrics:1.2.6",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.api:2.4.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.base:3.0.6",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.davex:1.3.10",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.jackrabbit.accessmanager:3.0.4",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.jackrabbit.usermanager:2.2.8",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.jcr-wrapper:2.0.0",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.registration:1.0.6",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.webconsole:1.0.2",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.jcr.webdav:2.3.8",
-            "start-order":"15"
-        },
-        {
-            "id":"org.apache.sling:org.apache.sling.resource.filter:1.0.0",
-            "start-order":"15"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.commons.log.LogManager":{
-            "org.apache.sling.commons.log.packagingDataEnabled":true,
-            "org.apache.sling.commons.log.pattern":"%d{dd.MM.yyyy HH:mm:ss.SSS} *%level* [%thread] %logger %msg%n",
-            "org.apache.sling.commons.log.level":"info",
-            "org.apache.sling.commons.log.file":"logs/error.log",
-            "org.apache.sling.commons.log.file.number:Integer":"7",
-            "org.apache.sling.commons.log.file.size":"'.'yyyy-MM-dd"
-        },
-        "org.apache.sling.engine.impl.log.RequestLogger":{
-            "access.log.enabled":true,
-            "request.log.outputtype:Integer":"0",
-            "access.log.output":"log.access",
-            "request.log.output":"log.request",
-            "request.log.enabled":true,
-            "access.log.outputtype:Integer":"0"
-        },
-        "org.apache.sling.jcr.davex.impl.servlets.SlingDavExServlet":{
-            "alias":"/server"
-        },
-        "org.apache.sling.jcr.webdav.impl.servlets.SimpleWebDavServlet":{
-            "dav.root":"/dav"
-        },
-        "org.apache.sling.commons.log.LogManager.factory.config~access.log":{
-            "org.apache.sling.commons.log.pattern":"%msg%n",
-            "org.apache.sling.commons.log.names":[
-                "log.access"
-            ],
-            "org.apache.sling.commons.log.level":"info",
-            "org.apache.sling.commons.log.file":"logs/access.log"
-        },
-        "org.apache.sling.commons.log.LogManager.factory.config~request.log":{
-            "org.apache.sling.commons.log.pattern":"%msg%n",
-            "org.apache.sling.commons.log.names":[
-                "log.request"
-            ],
-            "org.apache.sling.commons.log.level":"info",
-            "org.apache.sling.commons.log.file":"logs/request.log"
-        },
-        "org.apache.sling.jcr.base.internal.LoginAdminWhitelist.fragment~sling":{
-            "whitelist.bundles":[
-                "org.apache.sling.discovery.commons",
-                "org.apache.sling.discovery.base",
-                "org.apache.sling.discovery.oak",
-                "org.apache.sling.extensions.webconsolesecurityprovider",
-                "org.apache.sling.i18n",
-                "org.apache.sling.jcr.base",
-                "org.apache.sling.jcr.contentloader",
-                "org.apache.sling.jcr.jackrabbit.usermanager",
-                "org.apache.sling.jcr.oak.server",
-                "org.apache.sling.jcr.repoinit",
-                "org.apache.sling.jcr.webconsole",
-                "org.apache.sling.servlets.post",
-                "org.apache.sling.serviceuser.webconsole"
-            ],
-            "whitelist.name":"sling"
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~i18n":{
-            "user.mapping":[
-                "org.apache.sling.i18n=sling-i18n"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~jcr-install":{
-            "user.mapping":[
-                "org.apache.sling.installer.provider.jcr=sling-jcr-install"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~jcr-resource":{
-            "user.mapping":[
-                "org.apache.sling.jcr.resource:validation=sling-readall"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~observation":{
-            "user.mapping":[
-                "org.apache.sling.jcr.resource:observation=sling-readall"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~resourceresolver":{
-            "user.mapping":[
-                "org.apache.sling.resourceresolver:mapping=sling-mapping",
-                "org.apache.sling.resourceresolver:hierarchy=sling-readall",
-                "org.apache.sling.resourceresolver:observation=sling-readall",
-                "org.apache.sling.resourceresolver:console=sling-readall"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~servletsresolver":{
-            "user.mapping":[
-                "org.apache.sling.servlets.resolver:console=sling-readall",
-                "org.apache.sling.servlets.resolver:scripts=sling-scripting"
-            ]
-        },
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~xss":{
-            "user.mapping":[
-                "org.apache.sling.xss=sling-xss"
-            ]
-        }
-    }
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json
deleted file mode 100644
index 1628f03..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/sling_slingshot.json
+++ /dev/null
@@ -1,39 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling_slingshot:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.sling:org.apache.sling.sample.slingshot:0.9.0",
-            "start-order":"20"
-        }
-    ],
-    "configurations":{
-        "org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~sling.slingshot":{
-            "user.mapping":[
-                "org.apache.sling.sample.slingshot=slingshot-service"
-            ]
-        }
-    },
-    "repoinit:TEXT|true":[
-        "create service user slingshot-service",
-        "create user slingshot1 with password slingshot1",
-        "create user slingshot2 with password slingshot2",
-        "",
-        "create path (sling:Folder) /content/slingshot",
-        "create path (sling:Folder) /content/slingshot/users",
-        "create path (sling:Folder) /content/slingshot/users/slingshot1",
-        "create path (sling:Folder) /content/slingshot/users/slingshot2",
-        "",
-        "set ACL for slingshot-service",
-        "allow   jcr:read,rep:write    on /content/slingshot",
-        "end",
-        "",
-        "set ACL for slingshot1",
-        "allow   jcr:read,rep:write    on /content/slingshot/users/slingshot1",
-        "end",
-        "",
-        "set ACL for slingshot2",
-        "allow   jcr:read,rep:write    on /content/slingshot/users/slingshot2",
-        "end"
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json
deleted file mode 100644
index 4bf9d52..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/standalone_standalone.json
+++ /dev/null
@@ -1,16 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:standalone:12-SNAPSHOT",
-    "bundles":[
-        {
-            "id":"org.apache.felix:org.apache.felix.http.jetty:4.0.8",
-            "run-modes":":standalone",
-            "start-order":"5"
-        },
-        {
-            "id":"org.apache.felix:org.apache.felix.http.servlet-api:1.1.2",
-            "run-modes":":standalone",
-            "start-order":"5"
-        }
-    ]
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json b/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json
deleted file mode 100644
index 94fe38e..0000000
--- a/sling-org-apache-sling-feature-model-starter/src/main/fm/webapp_webapp.json
+++ /dev/null
@@ -1,4 +0,0 @@
-
-{
-    "id":"org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:webapp:12-SNAPSHOT"
-}
\ No newline at end of file
diff --git a/sling-org-apache-sling-feature-starter/Readme.md b/sling-org-apache-sling-feature-starter/Readme.md
new file mode 100644
index 0000000..cf65ebd
--- /dev/null
+++ b/sling-org-apache-sling-feature-starter/Readme.md
@@ -0,0 +1,23 @@
+# Sling Feature Starter
+
+This project is the Feature Model based version of the **sling-org-apache-sling-starter**
+module and creates an executable JAR file for now.
+It is also a test case for the Slingstart Feature Maven Plugin.
+
+## Build
+
+This plugin depends on the **Sling Start Maven Plugin** (also in the Sling
+Whiteboard) which is for now extracted in its own profile **launch**:
+
+1. Go to **sling-slingstart-feature-maven-plugin** module in Sling Whiteboard
+2. Build with: `mvn clean install`
+3. Go back to **sling-org-apache-sling-feature-starter**
+4. Build and Launch it with: `mvn clean install -P launch`
+5. Sling will come up and is accessible on the temporary port but the build
+will not end
+
+## Issues
+
+This module must be able to launch Sling in a demon (background) thread
+so that the starter can exit. The question is if that is added here or to
+the Feature Launcher module.
diff --git a/sling-org-apache-sling-feature-starter/pom.xml b/sling-org-apache-sling-feature-starter/pom.xml
index 0189bc3..593e430 100644
--- a/sling-org-apache-sling-feature-starter/pom.xml
+++ b/sling-org-apache-sling-feature-starter/pom.xml
@@ -32,18 +32,33 @@
         <sling.java.version>8</sling.java.version>
         <picocli.version>3.6.0</picocli.version>
         <appassembler-maven-plugin.version>2.0.0</appassembler-maven-plugin.version>
+        <org.apache.sling.feature.extension.content.version>1.0.4</org.apache.sling.feature.extension.content.version>
+        <org.apache.sling.feature.launcher.version>1.1.0</org.apache.sling.feature.launcher.version>
+        <org.apache.sling.feature.io.version>1.1.0</org.apache.sling.feature.io.version>
+        <org.apache.felix.converter.version>1.0.8</org.apache.felix.converter.version>
     </properties>
 
 <!--    <scm>-->
-<!--        <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git</connection>-->
-<!--        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git</developerConnection>-->
-<!--        <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-feature-launcher.git</url>-->
+<!--        <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-starter.git</connection>-->
+<!--        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-starter.git</developerConnection>-->
+<!--        <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-feature-starter.git</url>-->
 <!--        <tag>HEAD</tag>-->
 <!--    </scm>-->
 
     <build>
         <plugins>
             <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>ianal-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>verify-legal-files</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-dependency-plugin</artifactId>
                 <executions>
@@ -131,22 +146,22 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature.extension.content</artifactId>
-            <version>1.0.4</version>
+            <version>${org.apache.sling.feature.extension.content.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature.launcher</artifactId>
-            <version>1.1.0</version>
+            <version>${org.apache.sling.feature.launcher.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.feature.io</artifactId>
-            <version>1.1.0</version>
+            <version>${org.apache.sling.feature.io.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.converter</artifactId>
-            <version>1.0.8</version>
+            <version>${org.apache.felix.converter.version}</version>
         </dependency>
 
         <dependency>
@@ -168,4 +183,61 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
+    <profiles>
+        <profile>
+            <id>launch</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>reserve-network-port</id>
+                                <goals>
+                                    <!-- pre-integration-test is too late -->
+                                    <goal>reserve-network-port</goal>
+                                </goals>
+                                <phase>process-resources</phase>
+                                <configuration>
+                                    <portNames>
+                                        <portName>http.port</portName>
+                                        <portName>sling.control.port</portName>
+                                    </portNames>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.sling</groupId>
+                        <artifactId>slingstart-feature-maven-plugin</artifactId>
+                        <version>0.0.1-SNAPSHOT</version>
+                        <extensions>true</extensions>
+                        <executions>
+                            <execution>
+                                <id>start-container</id>
+                                <goals>
+                                    <goal>start</goal>
+                                    <goal>stop</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <launchpadJar>${project.build.directory}/${project.artifactId}-${project.version}.jar</launchpadJar>
+                            <parallelExecution>false</parallelExecution>
+<!--                            <createWebapp>false</createWebapp>-->
+                            <servers>
+                                <server>
+                                    <port>${http.port}</port>
+                                    <controlPort>${sling.control.port}</controlPort>
+                                    <debug>true</debug>
+                                    <stdOutFile>launchpad.out</stdOutFile>
+                                </server>
+                            </servers>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git a/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json b/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
index c847732..85b68c4 100644
--- a/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
+++ b/sling-org-apache-sling-feature-starter/src/main/resources/feature-sling12.json
@@ -1023,7 +1023,7 @@
     "org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:sling_slingshot:12-SNAPSHOT",
     "org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:standalone:12-SNAPSHOT",
     "org.apache.sling:org.apache.sling.feature.model.starter:slingfeature:webapp:12-SNAPSHOT",
-    "org.apache.sling:org.apache.sling.jcr.packageinit:slingosgifeature:0.0.1-SNAPSHOT"
+    "org.apache.sling:org.apache.sling.jcr.packageinit:slingosgifeature:jcr-packageinit:0.0.1-SNAPSHOT"
   ],
   "repoinit:TEXT|true":[
     "# general",
diff --git a/sling-slingstart-feature-maven-plugin/Readme.md b/sling-slingstart-feature-maven-plugin/Readme.md
new file mode 100644
index 0000000..fea9136
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/Readme.md
@@ -0,0 +1,51 @@
+# Sling Start Feature Maven Plugin
+
+This Maven Plugin is the Feature Model based version of the Slingstart
+Maven Plugin. It does not depend on the predecessor to keep the PM and FM
+based code base separate.
+
+## Build
+
+This plugin is built like usual with:
+```
+mvn clean install
+```
+
+## Usage
+
+The plugin can be used (see **sling-org-apache-sling-feature-starter**
+module in Sling Whiteboard) like this:
+```
+<plugin>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>slingstart-feature-maven-plugin</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <extensions>true</extensions>
+    <executions>
+        <execution>
+            <id>start-container</id>
+            <goals>
+                <goal>start</goal>
+                <goal>stop</goal>
+            </goals>
+        </execution>
+    </executions>
+    <configuration>
+        <launchpadJar>${project.build.directory}/${project.artifactId}-${project.version}.jar</launchpadJar>
+        <parallelExecution>false</parallelExecution>
+        <servers>
+            <server>
+                <port>${http.port}</port>
+                <controlPort>${sling.control.port}</controlPort>
+                <debug>true</debug>
+                <stdOutFile>launchpad.out</stdOutFile>
+            </server>
+        </servers>
+    </configuration>
+</plugin>
+```
+
+## Issues
+
+The Feature Launcher does not support to be started in the background and
+so this plugin will be not end the build when Sling is started.
diff --git a/sling-slingstart-feature-maven-plugin/pom.xml b/sling-slingstart-feature-maven-plugin/pom.xml
new file mode 100644
index 0000000..2b6891e
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/pom.xml
@@ -0,0 +1,348 @@
+<?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>35</version>
+        <relativePath />
+    </parent>
+
+    <artifactId>slingstart-feature-maven-plugin</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>maven-plugin</packaging>
+
+    <name>Apache Sling SlingStart Feature Maven Plugin</name>
+    <description>
+        Maven Plugin supporting Sling Feature Launchpad
+    </description>
+    <url>https://sling.apache.org/components/slingstart-maven-plugin/</url>
+
+    <properties>
+        <maven.version>3.0.5</maven.version>
+        <maven.site.path>${project.artifactId}-archives/${project.artifactId}-LATEST</maven.site.path>
+        <sling.java.version>8</sling.java.version>
+        <org.apache.sling.feature.extension.content.version>1.0.4</org.apache.sling.feature.extension.content.version>
+        <org.apache.sling.feature.launcher.version>1.1.0</org.apache.sling.feature.launcher.version>
+        <org.apache.sling.feature.io.version>1.1.0</org.apache.sling.feature.io.version>
+        <org.apache.felix.converter.version>1.0.8</org.apache.felix.converter.version>
+        <org.apache.sling.feature.starter.version>0.0.1-SNAPSHOT</org.apache.sling.feature.starter.version>
+        <org.apache.sling.feature.version>1.1.0</org.apache.sling.feature.version>
+        <org.apache.sling.feature.analyser.version>1.1.0</org.apache.sling.feature.analyser.version>
+        <org.apache.sling.feature.modelconverter.version>1.0.8</org.apache.sling.feature.modelconverter.version>
+    </properties>
+
+<!--    <scm>-->
+<!--        <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-slingstart-maven-plugin.git</connection>-->
+<!--        <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-slingstart-maven-plugin.git</developerConnection>-->
+<!--        <url>https://gitbox.apache.org/repos/asf?p=sling-slingstart-maven-plugin.git</url>-->
+<!--       <tag>HEAD</tag>-->
+<!--    </scm>-->
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-java</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <message>${project.name} must be compiled with Java 1.8 or higher.</message>
+                                    <version>1.${sling.java.version}.0</version>
+                                </requireJavaVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.plexus</groupId>
+                <artifactId>plexus-component-metadata</artifactId>
+                <version>1.7.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-metadata</id>
+                        <goals>
+                            <goal>generate-metadata</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>mojo-descriptor</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>descriptor</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>generated-helpmojo</id>
+                        <goals>
+                            <goal>helpmojo</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-scm-publish-plugin</artifactId>
+                <configuration>
+                    <checkoutDirectory>${user.home}/maven-sites/${maven.site.path}</checkoutDirectory>
+                    <tryUpdate>true</tryUpdate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>src/site/markdown/**</exclude>
+                        <exclude>src/test/resources/**</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <!-- for https://issues.apache.org/jira/browse/SUREFIRE-1067 -->
+                <version>2.20.1</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <!-- for https://issues.apache.org/jira/browse/SUREFIRE-855 -->
+                <version>2.20.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <systemPropertyVariables>
+                        <project.version>${project.version}</project.version>
+                    </systemPropertyVariables>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.sling</groupId>-->
+<!--            <artifactId>org.apache.sling.provisioning.model</artifactId>-->
+<!--            <version>1.8.4</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.starter</artifactId>
+            <version>${org.apache.sling.feature.starter.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature</artifactId>
+            <version>${org.apache.sling.feature.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.analyser</artifactId>
+            <version>${org.apache.sling.feature.analyser.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.modelconverter</artifactId>
+            <version>${org.apache.sling.feature.modelconverter.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.io</artifactId>
+            <version>${org.apache.sling.feature.io.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- for converting Maven to OSGi versions -->
+        <dependency>
+            <groupId>biz.aQute.bnd</groupId>
+            <artifactId>biz.aQute.bndlib</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-interactivity-api</artifactId>
+            <version>1.0-alpha-6</version>
+        </dependency>
+        <!-- We use a class from the config admin implementation to read config files -->
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configadmin</artifactId>
+            <version>1.8.10</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.converter</artifactId>
+            <version>1.0.10</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configurator</artifactId>
+            <version>1.0.10</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.johnzon</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-archiver</artifactId>
+            <version>2.4.4</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.codehaus.plexus</groupId>
+                    <artifactId>plexus-container-default</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.codehaus.plexus</groupId>
+                    <artifactId>plexus-component-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>3.0.17</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-filtering</artifactId>
+            <version>1.2</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>maven-project</artifactId>
+                    <groupId>org.apache.maven</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- The following artifacts are purely used by the unit tests
+            so these dependencies ensures that they are in the .m2 directory prior to executing the tests.
+            Whenever you modify these, you must also modify the references in org.apache.sling.maven.slingstart.PreparePackageMojoTest! -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.classloader</artifactId>
+            <version>1.3.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.contentdetection</artifactId>
+            <version>1.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.mime</artifactId>
+            <version>2.1.8</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.threads</artifactId>
+            <version>3.2.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </reporting>
+
+</project>
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java
new file mode 100644
index 0000000..94161f3
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/BuildConstants.java
@@ -0,0 +1,105 @@
+/*
+ * 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.maven.slingstart.feature;
+
+//import org.apache.sling.provisioning.model.ModelConstants;
+//import org.apache.sling.provisioning.model.io.ModelArchiveWriter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class BuildConstants {
+
+    // CONTEXTS
+    public static final String CONTEXT_GLOBAL = "slingstart:global";
+//    public static final String CONTEXT_STANDALONE = "slingstart" + ModelConstants.RUN_MODE_STANDALONE;
+//    public static final String CONTEXT_WEBAPP = "slingstart" + ModelConstants.RUN_MODE_WEBAPP;
+    public static final String CONTEXT_STANDALONE = "slingstart" + ":standalone";
+    public static final String CONTEXT_WEBAPP = "slingstart" + ":webapp";
+
+    // Model artifact name
+    public static final String MODEL_ARTIFACT_NAME = "slingstart.txt";
+
+    // Types
+
+    public static final String TYPE_JAR = "jar";
+
+    public static final String TYPE_WAR = "war";
+
+    public static final String TYPE_POM = "pom";
+
+    public static final String TYPE_TXT = "txt";
+
+    public static final String PACKAGING_PARTIAL_SYSTEM = "slingfeature";
+
+    public static final String PACKAGING_SLINGSTART = "slingstart";
+
+    // Classifiers
+
+    public static final String CLASSIFIER_PARTIAL_SYSTEM = "slingfeature";
+
+    public static final String CLASSIFIER_BASE = "base";
+
+    public static final String CLASSIFIER_APP = "app";
+
+    public static final String CLASSIFIER_WEBAPP = "webapp";
+
+//    public static final String CLASSIFIER_MAR = ModelArchiveWriter.DEFAULT_EXTENSION;
+
+    // Manifest attributes
+
+    public static final String ATTR_BUILT_BY = "Built-By";
+
+    public static final String ATTR_CREATED_BY = "Created-By";
+
+    public static final String ATTR_IMPLEMENTATION_VERSION = "Implementation-Version";
+
+    public static final String ATTR_IMPLEMENTATION_VENDOR = "Implementation-Vendor";
+
+    public static final String ATTR_IMPLEMENTATION_BUILD = "Implementation-Build";
+
+    public static final String ATTR_IMPLEMENTATION_VENDOR_ID = "Implementation-Vendor-Id";
+
+    public static final String ATTR_IMPLEMENTATION_TITLE = "Implementation-Title";
+
+    public static final String ATTR_SPECIFICATION_TITLE = "Specification-Title";
+
+    public static final String ATTR_SPECIFICATION_VENDOR = "Specification-Vendor";
+
+    public static final String ATTR_SPECIFICATION_VERSION = "Specification-Version";
+
+    public static final String ATTR_MAIN_CLASS = "Main-Class";
+
+    public static final String ATTR_VALUE_MAIN_CLASS = "org.apache.sling.launchpad.app.Main";
+
+    public static final List<String> ATTRS_EXCLUDES = new ArrayList<String>();
+    static {
+        ATTRS_EXCLUDES.add(ATTR_BUILT_BY);
+        ATTRS_EXCLUDES.add(ATTR_CREATED_BY);
+        ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VERSION);
+        ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VENDOR);
+        ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_BUILD);
+        ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_VENDOR_ID);
+        ATTRS_EXCLUDES.add(ATTR_IMPLEMENTATION_TITLE);
+        ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_TITLE);
+        ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_VENDOR);
+        ATTRS_EXCLUDES.add(ATTR_SPECIFICATION_VERSION);
+    }
+
+    // build constants
+    public static final String WEBAPP_OUTDIR = "slingstart-webapp";
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java
new file mode 100644
index 0000000..668756c
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Launcher.java
@@ -0,0 +1,96 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Launcher implements LauncherMBean {
+
+    private final int listenerPort;
+
+    public Launcher(final int listenerPort) {
+        this.listenerPort = listenerPort;
+    }
+
+    @Override
+    public void startupFinished() {
+        final List<String> hosts = new ArrayList<String>();
+        hosts.add("localhost");
+        hosts.add("127.0.0.1");
+
+        boolean done = false;
+        int index = 0;
+        while ( !done && index < hosts.size() ) {
+            final String hostName = hosts.get(index);
+            final int twoMinutes = 2 * 60 * 1000;
+
+            Socket clientSocket = null;
+            DataOutputStream out = null;
+            BufferedReader in = null;
+            try {
+                clientSocket = new Socket();
+                clientSocket.connect(new InetSocketAddress(hostName, listenerPort), twoMinutes);
+                // without that, read() call on the InputStream associated with this Socket is infinite
+                clientSocket.setSoTimeout(twoMinutes);
+
+                out = new DataOutputStream(clientSocket.getOutputStream());
+                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+                out.writeBytes("started\n");
+                in.readLine();
+                done = true;
+            } catch (final Throwable ignore) {
+                // catch Throwable because InetSocketAddress and Socket#connect throws unchecked exceptions
+                // we ignore this for now
+            } finally {
+                if ( in != null ) {
+                    try {
+                        in.close();
+                    } catch ( final IOException ioe) {
+                        // ignore
+                    }
+                }
+                if ( out != null ) {
+                    try {
+                        out.close();
+                    } catch ( final IOException ioe) {
+                        // ignore
+                    }
+                }
+                if ( clientSocket != null ) {
+                    try {
+                        clientSocket.close();
+                    } catch (final IOException e) {
+                        // ignore
+                    }
+                }
+            }
+            index++;
+        }
+    }
+
+    @Override
+    public void startupProgress(Float ratio) {
+        // nothing to do
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java
new file mode 100644
index 0000000..a221885
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.java
@@ -0,0 +1,34 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+/**
+ * The launcher MBean interface.
+ */
+public interface LauncherMBean {
+
+    /**
+     * Notify the launcher about the finish of the startup.
+     */
+    void startupFinished();
+
+    /**
+     * Notify the launcher about the progress of the startup.
+     * @param ratio Startup progress ratio
+     */
+    void startupProgress(Float ratio);
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java
new file mode 100644
index 0000000..9db0523
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/launcher/Main.java
@@ -0,0 +1,113 @@
+/*
+ * 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.maven.slingstart.feature.launcher;
+
+import aQute.bnd.build.Run;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+
+/**
+ * Main class for launching Apache Sling.
+ *
+ */
+public class Main {
+
+    /** Arguments to pass to the real main class */
+    private final String[] startupArgs;
+
+    /** Verbose flag */
+    private final boolean verbose;
+
+    /** App jar */
+    private final File appJar;
+
+    /** Listener port. */
+    private final int listenerPort;
+
+    /** Main class default value */
+    private final static String MAIN_CLASS_DEF = "org.apache.sling.feature.starter.app.SlingStarter";
+
+    /** Delimeter string */
+    private final static String DELIM =
+	    "-------------------------------------------------------------------";
+
+    /**
+     * Create a new launcher
+     * First argument is the launchpad jar
+     * Second argument is the listener port
+     * Third argument is verbose
+     */
+    public Main(final String[] args) {
+        if ( args == null || args.length < 3 ) {
+            throw new IllegalArgumentException("Missing configuration: " + args);
+        }
+        this.appJar = new File(args[0]);
+        this.listenerPort = Integer.valueOf(args[1]);
+        this.verbose = Boolean.valueOf(args[2]);
+        System.out.println("App Jar: " + appJar);
+        System.out.println("Listener Port: " + listenerPort);
+        System.out.println("Verbose: " + verbose);
+	    this.startupArgs = new String[args.length-3];
+	    System.arraycopy(args, 3, this.startupArgs, 0, this.startupArgs.length);
+    }
+
+    /**
+     * Startup
+     */
+    public void run() throws Exception {
+        if (verbose) {
+	        System.out.println(DELIM);
+            System.out.println("Slingstart application: " + this.appJar);
+            System.out.println("Main class: " + MAIN_CLASS_DEF);
+            System.out.println("Listener Port: " + String.valueOf(this.listenerPort));
+            System.out.println("Arguments: " + Arrays.toString(this.startupArgs));
+            System.out.println(DELIM);
+        }
+
+        final ClassLoader cl = new URLClassLoader(new URL[] {this.appJar.toURI().toURL()});
+        Thread.currentThread().setContextClassLoader(cl);
+
+        // create and register mbean
+        final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
+        jmxServer.registerMBean(new Launcher(this.listenerPort),
+                new ObjectName("org.apache.sling.feature.launchpad:type=Launcher"));
+
+        final Class<?> mainClass = cl.loadClass(MAIN_CLASS_DEF);
+        final Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
+        mainMethod.invoke(null, (Object)this.startupArgs);
+    }
+
+    public static void main(final String[] args) {
+        try {
+            final Main m = new Main(args);
+            m.run();
+        } catch(RuntimeException e) {
+            throw e;
+        } catch ( final Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+}
+
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java
new file mode 100644
index 0000000..2970289
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/AbstractStartStopMojo.java
@@ -0,0 +1,82 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.codehaus.plexus.components.interactivity.Prompter;
+import org.codehaus.plexus.components.interactivity.PrompterException;
+
+import java.io.File;
+import java.util.List;
+
+public abstract class AbstractStartStopMojo extends AbstractMojo {
+
+    /**
+     * Set this to "true" to skip starting the launchpad
+     */
+    @Parameter(property = "maven.test.skip", defaultValue = "false")
+    protected boolean skipLaunchpad;
+
+    /**
+     * Parameter containing the list of server configurations
+     */
+    @Parameter
+    protected List<ServerConfiguration> servers;
+
+    /**
+     * The system properties file will contain all started instances with their ports etc.
+     */
+    @Parameter(defaultValue = "${project.build.directory}/launchpad-runner.properties")
+    protected File systemPropertiesFile;
+
+    /**
+     * If {@code true} this mojo blocks until you press the Enter key.
+     */
+    @Parameter
+    protected boolean shouldBlockUntilKeyIsPressed;
+
+    @Component
+    private Prompter prompter;
+    
+    protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
+    
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (this.skipLaunchpad) {
+            this.getLog().info("Executing of this mojo is disabled by configuration.");
+            return;
+        }
+        
+        doExecute();
+    }
+
+    protected void blockIfNecessary() throws MojoFailureException {
+        if (shouldBlockUntilKeyIsPressed) {
+            // http://stackoverflow.com/a/21977269/5155923
+            try {
+                prompter.prompt("Press Enter to continue");
+            } catch (PrompterException e) {
+                throw new MojoFailureException("Could not prompt for user input. Maven is probably running in non-interactive mode! Do not use parameter 'shouldBlockUntilKeyIsPressed' in that case", e);
+            }
+        }
+
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java
new file mode 100644
index 0000000..0202a91
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ControlListener.java
@@ -0,0 +1,160 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * Control listener.
+ * This class listens for the startup of a launchpad instance.
+ */
+public class ControlListener implements Runnable {
+
+    // command sent by the client to notify startup
+    private static final String COMMAND_STARTED = "started";
+
+    private static final String RESPONSE_OK = "ok";
+
+    // The default interface to listen on
+    private static final String DEFAULT_LISTEN_INTERFACE = "127.0.0.1";
+
+    // The port to listen on
+    private final int port;
+
+    private volatile boolean started = false;
+
+    private volatile boolean stopped = false;
+
+    private volatile ServerSocket server;
+
+    public ControlListener(final int p) {
+        this.port = p;
+        final Thread listener = new Thread(this);
+        listener.setDaemon(true);
+        listener.setName("Launchapd startup listener");
+        listener.start();
+    }
+
+    public int getPort() {
+        return this.port;
+    }
+
+    public boolean isStarted() {
+        return this.started;
+    }
+
+    public void stop() {
+        stopped = true;
+        if ( server != null ) {
+            try {
+                server.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Implements the server thread receiving commands from clients and acting
+     * upon them.
+     */
+    @Override
+    public void run() {
+        final InetSocketAddress socketAddress = getSocketAddress(this.port);
+        try {
+            server = new ServerSocket();
+            server.bind(socketAddress);
+        } catch (final IOException ioe) {
+            return;
+        }
+
+        try {
+            while (!stopped) {
+
+                final Socket s = server.accept();
+
+                try {
+                    final String commandLine = readLine(s);
+                    if (commandLine == null) {
+                        final String msg = "ERR: missing command";
+                        writeLine(s, msg);
+                        continue;
+                    }
+
+                    final String command = commandLine;
+
+                    if (COMMAND_STARTED.equals(command)) {
+                        writeLine(s, RESPONSE_OK);
+                        this.started = true;
+                        this.stopped = true;
+                        break;
+
+                    } else {
+                        final String msg = "ERR:" + command;
+                        writeLine(s, msg);
+
+                    }
+                } finally {
+                    try {
+                        s.close();
+                    } catch (IOException ignore) {
+                    }
+                }
+            }
+        } catch (final IOException ioe) {
+            // ignore
+        } finally {
+            try {
+                server.close();
+            } catch (final IOException ignore) {
+                // ignore
+            }
+        }
+    }
+
+    private String readLine(final Socket socket) throws IOException {
+        final BufferedReader br = new BufferedReader(new InputStreamReader(
+            socket.getInputStream(), "UTF-8"));
+        return br.readLine();
+    }
+
+    private void writeLine(final Socket socket, final String line) throws IOException {
+        final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
+            socket.getOutputStream(), "UTF-8"));
+        bw.write(line);
+        bw.write("\r\n");
+        bw.flush();
+    }
+
+    private static InetSocketAddress getSocketAddress(final int port) {
+        final String address = DEFAULT_LISTEN_INTERFACE;
+
+        final InetSocketAddress addr = new InetSocketAddress(address, port);
+        if (!addr.isUnresolved()) {
+            return addr;
+        }
+
+        return null;
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java
new file mode 100644
index 0000000..d05c4e4
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LauncherCallable.java
@@ -0,0 +1,369 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.shared.utils.StringUtils;
+import org.apache.sling.maven.slingstart.feature.launcher.Main;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.lang.ProcessBuilder.Redirect;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A callable for launchpad an instance
+ */
+public class LauncherCallable implements Callable<ProcessDescription> {
+
+    private final LaunchpadEnvironment environment;
+    private final ServerConfiguration configuration;
+    private final Log logger;
+
+    public LauncherCallable(final Log logger,
+                                  final ServerConfiguration configuration,
+                                  final LaunchpadEnvironment environment) {
+        this.logger = logger;
+        this.configuration = configuration;
+        this.environment = environment;
+    }
+
+    /**
+     * @see Callable#call()
+     */
+    @Override
+    public ProcessDescription call() throws Exception {
+
+        // fail if launchpad with this id is already started
+        if (!ProcessDescriptionProvider.getInstance().isRunConfigurationAvailable(configuration.getId())) {
+            throw new Exception("Launchpad with id " + configuration.getId() + " is not available");
+        }
+
+        // get the launchpad jar
+        final File launchpad = this.environment.prepare(this.configuration.getFolder());
+
+        // Lock the launchpad id
+        final String launchpadKey = ProcessDescriptionProvider.getInstance().getId(configuration.getId());
+
+        // start launchpad
+        ProcessDescription cfg = this.start(launchpad);
+
+        // Add thread hook to shutdown launchpad
+        if (environment.isShutdownOnExit()) {
+            cfg.installShutdownHook();
+        }
+
+        // Add configuration to the config provider
+        ProcessDescriptionProvider.getInstance().addRunConfiguration(cfg, launchpadKey);
+
+        boolean started = false;
+        try {
+            final long endTime = System.currentTimeMillis() + this.environment.getReadyTimeOutSec() * 1000;
+            boolean finished = false;
+            while ( !started && !finished && System.currentTimeMillis() < endTime ) {
+                Thread.sleep(5000);
+                started = cfg.getControlListener().isStarted();
+                try {
+                    // if we get an exit value, the process has stopped
+                    cfg.getProcess().exitValue();
+                    finished = true;
+                } catch ( final IllegalThreadStateException itse) {
+                    // everything as expected
+                }
+                
+            }
+
+            if ( finished ) {
+                throw new Exception("Launchpad did exit unexpectedly.");
+            }
+            if ( !started ) {
+                throw new Exception("Launchpad did not start successfully in " + this.environment.getReadyTimeOutSec() + " seconds.");
+            }
+            // now check for the availability of the HTTP port
+            boolean httpAvailable = isLocalhostPortAvailable(Integer.valueOf(this.configuration.getPort()));
+            // repeat until http service is up as well
+            while ( !httpAvailable && System.currentTimeMillis() < endTime ) {
+                Thread.sleep(1000);
+                httpAvailable = isLocalhostPortAvailable(Integer.valueOf(this.configuration.getPort()));
+            }
+            if ( !httpAvailable ) {
+                throw new Exception("Launchpad did not start http service on port " + this.configuration.getPort() + " successfully in " + this.environment.getReadyTimeOutSec() + " seconds.");
+            }
+            this.logger.info("Started Launchpad '" + configuration.getId() +
+                    "' at port " + configuration.getPort()+ " [run modes: " + configuration.getRunmode()+ "]");
+        } finally {
+            // stop control port
+            cfg.getControlListener().stop();
+
+            // call launchpad stop routine if not properly started
+            if (!started) {
+                stop(this.logger, cfg);
+                ProcessDescriptionProvider.getInstance().removeRunConfiguration(cfg.getId());
+                cfg = null;
+            }
+        }
+
+        return cfg;
+    }
+
+    private boolean isLocalhostPortAvailable(int port) throws IOException {
+        // https://stackoverflow.com/questions/46436813/difference-between-a-connection-refused-exception-and-a-timeout-in-httpclient
+        Socket clientSocket = new Socket();
+        try {
+            clientSocket.connect(new InetSocketAddress("127.0.0.1", port), 500);
+            // without that, read() call on the InputStream associated with this Socket is infinite
+            this.logger.debug("Successfully connected to localhost, port " + port);
+            clientSocket.close();
+            return true;
+        } catch (SocketTimeoutException e) {
+            // we ran into a timeout (port most probably blocked by firewall)
+            this.logger.debug("Ran into a timeout while connecting to localhost, port " + port, e);
+            return false;
+        } catch (ConnectException e) {
+            // port not bound
+            this.logger.debug("Could not connect to localhost, port " + port, e);
+            return false;
+        } finally {
+            clientSocket.close();
+        }
+    }
+
+    public boolean isRunning() {
+        return getControlPortFile(this.configuration.getFolder()).exists();
+    }
+
+    private void add(final List<String> args, final String value) {
+        if ( value != null ) {
+            final String[] single = value.trim().split(" ");
+            for(final String v : single) {
+                if ( v.trim().length() > 0 ) {
+                    args.add(v.trim());
+                }
+            }
+        }
+    }
+
+    private ProcessDescription start(final File jar) throws Exception {
+        final ProcessDescription cfg = new ProcessDescription(this.configuration.getId(), this.configuration.getFolder());
+
+        final ProcessBuilder builder = new ProcessBuilder();
+        final List<String> args = new ArrayList<String>();
+
+        String javaHome = System.getenv("JAVA_HOME");
+        String javaCmd = javaHome != null ? Paths.get(javaHome, "bin", "java").toString() : "java";
+
+        args.add(javaCmd);
+        add(args, this.configuration.getVmOpts());
+        add(args, this.configuration.getVmDebugOpts(this.environment.getDebug()));
+
+        args.add("-cp");
+        args.add("bin");
+        args.add(Main.class.getName());
+        // first three arguments: jar, listener port, verbose
+        args.add(jar.getPath());
+        args.add(String.valueOf(cfg.getControlListener().getPort()));
+        args.add("true");
+
+        // from here on launchpad properties
+        add(args, this.configuration.getOpts());
+
+        final String contextPath = this.configuration.getContextPath();
+        if ( contextPath != null && contextPath.length() > 0 && !contextPath.equals("/") ) {
+            args.add("-r");
+            args.add(contextPath);
+        }
+
+        if ( this.configuration.getPort() != null ) {
+            args.add("-p");
+            args.add(this.configuration.getPort());
+        }
+
+        if ( this.configuration.getControlPort() != null ) {
+            args.add("-j");
+            args.add(this.configuration.getControlPort());
+        }
+        if ( this.configuration.getRunmode() != null && this.configuration.getRunmode().length() > 0 ) {
+            args.add("-Dsling.run.modes=" + this.configuration.getRunmode());
+        }
+        if ( !this.environment.isShutdownOnExit() ) {
+            args.add("start");
+        }
+
+        builder.command(args.toArray(new String[args.size()]));
+        builder.directory(this.configuration.getFolder());
+        builder.redirectErrorStream(true);
+        logger.info("Starting Launchpad " + this.configuration.getId() +  "...");
+        String stdOutFile = this.configuration.getStdOutFile();
+        if (StringUtils.isNotBlank(stdOutFile)) {
+            File absoluteStdOutFile = new File(builder.directory(), stdOutFile);
+            // make sure to create the parent directories (if they do not exist yet)
+            absoluteStdOutFile.getParentFile().mkdirs();
+            builder.redirectOutput(absoluteStdOutFile);
+            logger.info("Redirecting stdout and stderr to " + absoluteStdOutFile);
+        } else {
+            builder.redirectOutput(Redirect.INHERIT);
+        }
+
+        logger.debug("Launchpad cmd: " + builder.command());
+        logger.debug("Launchpad dir: " + builder.directory());
+
+        try {
+            logger.info("Before Builder start()");
+            cfg.setProcess(builder.start());
+            logger.info("After Builder start(), cfg: " + cfg);
+        } catch (final IOException e) {
+            if (cfg.getProcess() != null) {
+                cfg.getProcess().destroy();
+                cfg.setProcess(null);
+            }
+            throw new Exception("Could not start the Launchpad", e);
+        }
+
+        return cfg;
+    }
+
+    public static void stop(final Log LOG, final ProcessDescription cfg) throws Exception {
+        boolean isNew = false;
+
+        if (cfg.getProcess() != null || isNew ) {
+            LOG.info("Stopping Launchpad '" + cfg.getId() + "'");
+            boolean destroy = true;
+            final int twoMinutes = 2 * 60 * 1000;
+            final File controlPortFile = getControlPortFile(cfg.getDirectory());
+            LOG.debug("Control port file " + controlPortFile + " exists: " + controlPortFile.exists());
+            if ( controlPortFile.exists() ) {
+                // reading control port
+                int controlPort = -1;
+                String secretKey = null;
+                LineNumberReader lnr = null;
+                String serverName = null;
+                try {
+                    lnr = new LineNumberReader(new FileReader(controlPortFile));
+                    final String portLine = lnr.readLine();
+                    final int pos = portLine.indexOf(':');
+                    controlPort = Integer.parseInt(portLine.substring(pos + 1));
+                    if ( pos > 0 ) {
+                        serverName = portLine.substring(0, pos);
+                    }
+                    secretKey = lnr.readLine();
+                } catch ( final NumberFormatException ignore) {
+                    // we ignore this
+                    LOG.debug("Error reading control port file " + controlPortFile, ignore);
+                } catch ( final IOException ignore) {
+                    // we ignore this
+                    LOG.debug("Error reading control port file " + controlPortFile, ignore);
+                } finally {
+                    IOUtils.closeQuietly(lnr);
+                }
+
+                if ( controlPort != -1 ) {
+                    final List<String> hosts = new ArrayList<String>();
+                    if ( serverName != null ) {
+                        hosts.add(serverName);
+                    }
+                    hosts.add("localhost");
+                    hosts.add("127.0.0.1");
+                    LOG.debug("Found control port " + controlPort);
+                    int index = 0;
+                    while ( destroy && index < hosts.size() ) {
+                        final String hostName = hosts.get(index);
+
+                        Socket clientSocket = null;
+                        DataOutputStream out = null;
+                        BufferedReader in = null;
+                        try {
+                            LOG.debug("Trying to connect to " + hostName + ":" + controlPort);
+                            clientSocket = new Socket();
+                            // set a socket timeout
+                            clientSocket.connect(new InetSocketAddress(hostName, controlPort), twoMinutes);
+                            // without that, read() call on the InputStream associated with this Socket is infinite
+                            clientSocket.setSoTimeout(twoMinutes);
+
+                            LOG.debug(hostName + ":" + controlPort + " connection estabilished, sending the 'stop' command...");
+
+                            out = new DataOutputStream(clientSocket.getOutputStream());
+                            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+                            if (secretKey != null) {
+                                out.writeBytes(secretKey);
+                                out.write(' ');
+                            }
+                            out.writeBytes("stop\n");
+                            in.readLine();
+                            destroy = false;
+                            LOG.debug("'stop' command sent to " + hostName + ":" + controlPort);
+                        } catch (final Throwable ignore) {
+                            // catch Throwable because InetSocketAddress and Socket#connect throws unchecked exceptions
+                            // we ignore this for now
+                            LOG.debug("Error sending 'stop' command to " + hostName + ":" + controlPort + " due to: " + ignore.getMessage());
+                        } finally {
+                            IOUtils.closeQuietly(in);
+                            IOUtils.closeQuietly(out);
+                            IOUtils.closeQuietly(clientSocket);
+                        }
+                        index++;
+                    }
+                }
+            }
+            if ( cfg.getProcess() != null ) {
+                final Process process = cfg.getProcess();
+
+                if (!destroy) {
+                    LOG.debug("Waiting for process to stop...");
+                    process.waitFor(twoMinutes, TimeUnit.MILLISECONDS);
+                    if (process.isAlive()) {
+                        LOG.debug("Process timeout out after 2 minutes");
+                        destroy = true;
+                    } else {
+                        LOG.debug("Process stopped");
+                    }
+                }
+
+                if (destroy) {
+                    LOG.debug("Destroying process...");
+                    process.destroy();
+                    process.waitFor(twoMinutes, TimeUnit.MILLISECONDS);
+                    LOG.debug("Process destroyed");
+                }
+
+                cfg.setProcess(null);
+            }
+        } else {
+            LOG.warn("Launchpad already stopped");
+        }
+    }
+
+    private static File getControlPortFile(final File directory) {
+        final File launchpadDir = new File(directory, LaunchpadEnvironment.WORK_DIR_NAME);
+        final File confDir = new File(launchpadDir, "conf");
+        final File controlPortFile = new File(confDir, "controlport");
+        return controlPortFile;
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java
new file mode 100644
index 0000000..150679c
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/LaunchpadEnvironment.java
@@ -0,0 +1,152 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Common settings for all launchpad instances.
+ */
+public class LaunchpadEnvironment {
+
+    /** The work directory created by starting launchpad. */
+    public static final String WORK_DIR_NAME = "sling";
+
+    private final File launchpadJar;
+    private final boolean cleanWorkingDirectory;
+    private final boolean shutdownOnExit;
+    private final int readyTimeOutSec;
+    private final String debug;
+
+    public LaunchpadEnvironment(final File launchpadJar,
+                                final boolean cleanWorkingDirectory,
+                                final boolean shutdownOnExit,
+                                final int readyTimeOutSec,
+                                final String debug) {
+        this.launchpadJar = launchpadJar;
+        this.cleanWorkingDirectory = cleanWorkingDirectory;
+        this.shutdownOnExit = shutdownOnExit;
+        this.readyTimeOutSec = readyTimeOutSec;
+        this.debug = debug;
+    }
+
+    public boolean isShutdownOnExit() {
+        return this.shutdownOnExit;
+    }
+
+    public int getReadyTimeOutSec() {
+        return this.readyTimeOutSec;
+    }
+
+    /**
+     * Check if the launchpad folder exists.
+     */
+    private void ensureFolderExists(final File folder) {
+        if (!folder.exists()) {
+            folder.mkdirs();
+        }
+        if (this.cleanWorkingDirectory) {
+            final File work = new File(folder, WORK_DIR_NAME);
+            org.apache.commons.io.FileUtils.deleteQuietly(work);
+        }
+    }
+
+    private File installLaunchpad(final File folder) throws IOException {
+        if (this.launchpadJar.getParentFile().getAbsolutePath().equals(folder.getAbsolutePath())) {
+            return this.launchpadJar;
+        }
+        try {
+            FileUtils.copyFileToDirectory(this.launchpadJar, folder);
+            return new File(folder, this.launchpadJar.getName());
+        } catch (final IOException ioe) {
+            throw new IOException("Unable to copy " + this.launchpadJar + " to " + folder, ioe);
+        }
+    }
+
+    private void installLauncher(final File folder) throws IOException {
+        final File binDir = new File(folder, "bin");
+        copyResource("org/apache/sling/maven/slingstart/feature/launcher/Launcher.class", binDir);
+        copyResource("org/apache/sling/maven/slingstart/feature/launcher/LauncherMBean.class", binDir);
+        copyResource("org/apache/sling/maven/slingstart/feature/launcher/Main.class", binDir);
+    }
+
+    /**
+     * Prepare a new instance.
+     * @param folder The target folder for the instance
+     * @return The launchpad jar
+     * @throws IOException if an error occurs.
+     */
+    public File prepare(final File folder) throws IOException {
+        this.ensureFolderExists(folder);
+
+        // copy launchpadJar
+        final File launchpad = this.installLaunchpad(folder);
+
+        // install launcher
+        this.installLauncher(folder);
+
+        return launchpad;
+    }
+
+    private void copyResource(final String resource,
+            final File dir)
+    throws IOException {
+        final int lastSlash = resource.lastIndexOf('/');
+        final File baseDir;
+        if ( lastSlash > 0 ) {
+            final String filePath = resource.substring(0, lastSlash).replace('/', File.separatorChar);
+            baseDir = new File(dir, filePath);
+        } else {
+            baseDir = dir;
+        }
+        baseDir.mkdirs();
+        final File file = new File(baseDir, resource.substring(lastSlash + 1));
+        final InputStream is = LaunchpadEnvironment.class.getClassLoader().getResourceAsStream(resource);
+        if ( is == null ) {
+            throw new IOException("Resource not found: " + resource);
+        }
+        final FileOutputStream fos = new FileOutputStream(file);
+        final byte[] buffer = new byte[2048];
+        int l;
+        try {
+            while ( (l = is.read(buffer)) > 0 ) {
+                fos.write(buffer, 0, l);
+            }
+        } finally {
+            if ( fos != null ) {
+                fos.close();
+            }
+            if ( is != null ) {
+                is.close();
+            }
+        }
+    }
+
+    /**
+     * 
+     * @return the global debug parameter for all Sling instances. Set through {@link StartMojo#debug}.
+     */
+    public String getDebug() {
+        return debug;
+    }
+
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java
new file mode 100644
index 0000000..23d64c3
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/PortHelper.java
@@ -0,0 +1,49 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple helper class to find a new port.
+ */
+public class PortHelper {
+
+    private static final Set<Integer> USED_PORTS = new HashSet<Integer>();
+
+    public static synchronized int getNextAvailablePort()
+            throws MojoExecutionException {
+        int unusedPort = 0;
+        do {
+            try {
+                final ServerSocket socket = new ServerSocket( 0 );
+                unusedPort = socket.getLocalPort();
+                socket.close();
+            } catch ( final IOException e ) {
+                throw new MojoExecutionException( "Error getting an available port from system", e );
+            }
+        } while ( USED_PORTS.contains(unusedPort));
+        USED_PORTS.add(unusedPort);
+
+        return unusedPort;
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java
new file mode 100644
index 0000000..ca8c563
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescription.java
@@ -0,0 +1,81 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import java.io.File;
+
+/**
+ * A running launchpad process.
+ */
+public class ProcessDescription {
+
+    private final String id;
+    private final File directory;
+    private final ControlListener listener;
+    private volatile Process process;
+
+    public ProcessDescription(final String id, final File directory) throws MojoExecutionException {
+        this.id = id;
+        this.directory = directory;
+        this.listener = new ControlListener(PortHelper.getNextAvailablePort());
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public File getDirectory() {
+        return directory;
+    }
+
+    public ControlListener getControlListener() {
+        return this.listener;
+    }
+
+    public Process getProcess() {
+        return process;
+    }
+
+    public void setProcess(final Process process) {
+        this.process = process;
+    }
+
+    /**
+     * Install a shutdown hook
+     */
+    public void installShutdownHook() {
+        final ProcessDescription cfg = this;
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override
+            public void run() {
+                if ( cfg.getProcess() != null ) {
+                    System.out.println("Terminating launchpad " + cfg.getId());
+                    cfg.getProcess().destroy();
+                    cfg.setProcess(null);
+                }
+            }
+        });
+    }
+
+    @Override
+    public String toString() {
+        return "RunningProcessDescription [id=" + id + ", directory="
+                + directory + ", process=" + process + "]";
+    }
+}
\ No newline at end of file
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java
new file mode 100644
index 0000000..cfb22e8
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ProcessDescriptionProvider.java
@@ -0,0 +1,106 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A singleton which is responsible to provide {@link ProcessDescription}s
+ */
+public class ProcessDescriptionProvider {
+
+    private static final String DEFAULT_KEY = "DEFAULT_LAUNCHPAD";
+
+    private static ProcessDescriptionProvider ourInstance = new ProcessDescriptionProvider();
+    private final Map<String, ProcessDescription> configs = new HashMap<String, ProcessDescription>();
+    private final Map<String, String> lockedIds = new HashMap<String, String>();
+
+    private ProcessDescriptionProvider() {
+        // private constructor
+    }
+
+    public static ProcessDescriptionProvider getInstance() {
+        return ourInstance;
+    }
+
+    /**
+     * Prepare an ID for a launchpad that will be started, before saving the config.
+     * @param launchpadId the id of the launchpad to lock
+     * @return id key used to add to configs
+     */
+    public synchronized String getId(final String launchpadId) throws Exception {
+        final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+        if (configs.containsKey(id) || lockedIds.containsKey(id)) {
+            throw new Exception("Launchpad Id " + id + " is already in use");
+        }
+
+        String ts = String.valueOf(System.currentTimeMillis());
+        lockedIds.put(id, ts);
+        return ts;
+    }
+
+    /**
+     *
+     * @param launchpadId
+     * @param unlockKey
+     * @return
+     */
+    public synchronized boolean cancelId(final String launchpadId, final String unlockKey) {
+        final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+        if (lockedIds.containsKey(id) && lockedIds.get(id).equals(unlockKey)) {
+            lockedIds.remove(id);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     *
+     * @param launchpadId
+     * @return
+     */
+    public synchronized ProcessDescription getRunConfiguration(final String launchpadId) {
+        final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+        return configs.get(id);
+    }
+
+    /**
+     *
+     * @param launchpadId
+     * @return
+     */
+    public synchronized  boolean isRunConfigurationAvailable(final String launchpadId) {
+        return getRunConfiguration(launchpadId) == null && !lockedIds.containsKey(launchpadId);
+    }
+
+    public synchronized void addRunConfiguration(ProcessDescription cfg, final String unlockKey) throws Exception {
+        String id = cfg.getId() == null ? DEFAULT_KEY : cfg.getId();
+        if (!lockedIds.containsKey(id) || !lockedIds.get(id).equals(unlockKey)) {
+            throw new Exception("Cannot add configuration. Id " + id + " doesn't exist");
+        }
+        lockedIds.remove(cfg.getId());
+        configs.put(cfg.getId(), cfg);
+    }
+
+    public synchronized void removeRunConfiguration(final String launchpadId) {
+        final String id = (launchpadId == null ? DEFAULT_KEY : launchpadId);
+        configs.remove(id);
+    }
+
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java
new file mode 100644
index 0000000..1a5051f
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/ServerConfiguration.java
@@ -0,0 +1,219 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * A server configuration
+ */
+public class ServerConfiguration implements Serializable {
+
+    private static final long serialVersionUID = 1922175510880318125L;
+
+    private static final String DEFAULT_VM_OPTS = "-Xmx1024m -XX:MaxPermSize=256m -Djava.awt.headless=true";
+
+    // http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation
+    private static final String DEFAULT_VM_DEBUG_OPTS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000";
+
+    /** The unique id. */
+    private String id;
+
+    /** The run mode string. */
+    private String runmode;
+
+    /** The port to use. */
+    private String port;
+
+    /** The control port to use. */
+    private String controlPort;
+
+    /** The context path. */
+    private String contextPath;
+
+    /** The vm options. */
+    private String vmOpts = DEFAULT_VM_OPTS;
+
+    /** 
+     * If set to {@code "true"}, the process will allow a debugger to connect on port 8000. 
+     * If set to some other string, that string will be appended to this server's {@code vmOpts}, allowing you to configure arbitrary debugging options.
+     * If the global configuration property {@link StartMojo#debug} is set on the mojo itself, it will be used instead.
+     */
+    private String debug;
+
+    /** Additional application options. */
+    private String opts;
+
+    /** Number of instances. */
+    private int instances = 1;
+
+    /** The folder to use. */
+    private File folder;
+    
+    /**
+     * The relative filename of the file which receives both the standard output (stdout) and standard error (stderr) of the server processes. 
+     * If null or empty string the server process inherits stdout from the parent process (i.e. the Maven process).
+     * The given filename must be relative to the working directory of the according server.
+     */
+    private String stdOutFile;
+
+    /**
+     * Get the instance id
+     * @return The instance id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Set the instance id
+     * @param id New instance id
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getRunmode() {
+        return runmode;
+    }
+
+    public void setRunmode(final String runmode) {
+        this.runmode = runmode;
+    }
+
+    public String getPort() {
+        return port;
+    }
+
+    public void setPort(final String port) {
+        this.port = port;
+    }
+
+    public String getContextPath() {
+        return contextPath;
+    }
+
+    public void setContextPath(final String contextPath) {
+        this.contextPath = contextPath;
+    }
+
+    public String getVmOpts() {
+        return vmOpts;
+    }
+
+    public void setVmOpts(final String vmOpts) {
+        this.vmOpts = vmOpts;
+    }
+
+    /**
+     * Returns the debugging options derived from the passed globalDebug parameter and the debug field (where the globalDebug parameter has precedence over the local field)
+     * @param globalDebug the global debug options (may be {@code null}).
+     * @return the debugging options to use or {@code null}. Should be appended to the ones being returned by {@link #getVmOpts()}.
+     * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/conninv.html#Invocation">JPDA Sun VM Invocation Options</a>
+     */
+    public String getVmDebugOpts(String globalDebug) {
+        if (globalDebug != null) {
+            if (Boolean.valueOf(globalDebug).equals(Boolean.TRUE)) {
+                return DEFAULT_VM_DEBUG_OPTS;
+            }
+            return globalDebug;
+        }
+        if (Boolean.valueOf(debug).equals(Boolean.TRUE)) {
+            return DEFAULT_VM_DEBUG_OPTS;
+        }
+        return debug;
+    }
+
+    public void setDebug(final String debug) {
+        this.debug = debug;
+    }
+
+    public String getOpts() {
+        return opts;
+    }
+
+    public void setOpts(final String opts) {
+        this.opts = opts;
+    }
+
+    public int getInstances() {
+        return this.instances;
+    }
+
+    public void setInstances(final int value) {
+        this.instances = value;
+    }
+
+    public File getFolder() {
+        return folder;
+    }
+
+    public void setFolder(final File folder) {
+        this.folder = folder.getAbsoluteFile();
+    }
+
+    public String getControlPort() {
+        return controlPort;
+    }
+
+    public void setControlPort(String controlPort) {
+        this.controlPort = controlPort;
+    }
+
+    public String getStdOutFile() {
+        return stdOutFile;
+    }
+
+    public void setStdOutFile(String stdOutFile) {
+        this.stdOutFile = stdOutFile;
+    }
+
+    /**
+     * Get the server
+     * @return The server
+     */
+    public String getServer() {
+        // hard coded for now
+        return "localhost";
+    }
+
+    public ServerConfiguration copy() {
+        final ServerConfiguration copy = new ServerConfiguration();
+        // we do not copy the id
+        copy.setRunmode(this.getRunmode());
+        copy.setPort(this.getPort());
+        copy.setContextPath(this.getContextPath());
+        copy.setVmOpts(this.getVmOpts());
+        copy.setDebug(this.debug);
+        copy.setOpts(this.getOpts());
+        copy.setInstances(1);
+        copy.setFolder(this.getFolder());
+        copy.setControlPort(this.getControlPort());
+        copy.setStdOutFile(this.stdOutFile);
+        return copy;
+    }
+
+    @Override
+    public String toString() {
+        return "LaunchpadConfiguration [id=" + id + ", runmode=" + runmode
+                + ", port=" + port + ", controlPort=" + controlPort
+                + ", contextPath=" + contextPath
+                + ", vmOpts=" + vmOpts + ", vmDebugOpts=" + getVmDebugOpts(null) + ", opts=" + opts + ", instances="
+                + instances + ", folder=" + folder + ", stdout=" + stdOutFile + "]";
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java
new file mode 100644
index 0000000..1915303
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StartMojo.java
@@ -0,0 +1,461 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.sling.maven.slingstart.feature.BuildConstants;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Start one or multiple launchpad instance(s).
+ */
+@Mojo(
+        name = "start",
+        defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST,
+        threadSafe = true
+    )
+public class StartMojo extends AbstractStartStopMojo {
+
+    /**
+     * Overwrites debug parameter of all server configurations (if set).
+     * Attaches a debugger to the forked JVM. If set to {@code "true"}, the process will allow a debugger to connect on port 8000.
+     * If set to some other string, that string will be appended to the server's {@code vmOpts}, allowing you to configure arbitrary debugging options.
+     */
+    @Parameter(property = "launchpad.debug")
+    protected String debug;
+
+    /**
+     * Ready timeout in seconds. If the launchpad has not been started in this
+     * time, it's assumed that the startup failed.
+     */
+    @Parameter(property = "launchpad.ready.timeout", defaultValue = "600")
+    private int launchpadReadyTimeOutSec;
+
+    /**
+     * The launchpad jar. This option has precedence over "launchpadDependency".
+     */
+    @Parameter(property = "launchpad.jar")
+    private File launchpadJar;
+
+    /**
+     * The launchpad jar as a dependency. This is only used if "launchpadJar" is not
+     * specified.
+     */
+    @Parameter
+    private Dependency launchpadDependency;
+
+    /**
+     * Clean the working directory before start.
+     */
+    @Parameter(property = "launchpad.clean.workdir", defaultValue = "false")
+    private boolean cleanWorkingDirectory;
+
+    /**
+     * Keep the launchpad running.
+     * @deprecated Use {@link AbstractStartStopMojo# blockUntilKeyIsPressed} instead.
+     */
+    @Deprecated
+    @Parameter(property = "launchpad.keep.running", defaultValue = "false")
+    private boolean keepLaunchpadRunning;
+
+    /**
+     * Set the execution of launchpad instances to be run in parallel (threads)
+     */
+    @Parameter(property = "launchpad.parallelExecution", defaultValue = "true")
+    private boolean parallelExecution;
+
+    /**
+     * The Maven project.
+     */
+    @Parameter(property = "project", readonly = true, required = true)
+    private MavenProject project;
+
+    /**
+     * The Maven session.
+     */
+    @Parameter(property = "session", readonly = true, required = true)
+    private MavenSession mavenSession;
+
+    @Component
+    private ArtifactHandlerManager artifactHandlerManager;
+
+    /**
+     * Used to look up Artifacts in the remote repository.
+     *
+     */
+    @Component
+    private ArtifactResolver resolver;
+
+    /**
+     * Get a resolved Artifact from the coordinates provided
+     *
+     * @return the artifact, which has been resolved.
+     * @throws MojoExecutionException
+     */
+    private Artifact getArtifact(final Dependency d)
+            throws MojoExecutionException {
+        final Artifact prjArtifact = new DefaultArtifact(d.getGroupId(),
+                        d.getArtifactId(),
+                        VersionRange.createFromVersion(d.getVersion()),
+                        d.getScope(),
+                        d.getType(),
+                        d.getClassifier(),
+                        this.artifactHandlerManager.getArtifactHandler(d.getType()));
+        try {
+            this.resolver.resolve(prjArtifact, this.project.getRemoteArtifactRepositories(), this.mavenSession.getLocalRepository());
+        } catch (final ArtifactResolutionException e) {
+            throw new MojoExecutionException("Unable to get artifact for " + d, e);
+        } catch (ArtifactNotFoundException e) {
+            throw new MojoExecutionException("Unable to get artifact for " + d, e);
+        }
+
+        return prjArtifact;
+    }
+
+    
+    @Override
+    protected void doExecute() throws MojoExecutionException, MojoFailureException {
+        // delete properties
+        if ( systemPropertiesFile != null && systemPropertiesFile.exists() ) {
+            FileUtils.deleteQuietly(this.systemPropertiesFile);
+        }
+
+        // get configurations
+        final Collection<ServerConfiguration> configurations = getLaunchpadConfigurations();
+
+        // create the common environment
+        final LaunchpadEnvironment env = new LaunchpadEnvironment(this.findLaunchpadJar(),
+                this.cleanWorkingDirectory,
+                !this.keepLaunchpadRunning,
+                this.launchpadReadyTimeOutSec,
+                this.debug);
+
+        // create callables
+        final Collection<LauncherCallable> tasks = new LinkedList<LauncherCallable>();
+
+        for (final ServerConfiguration launchpadConfiguration : configurations) {
+            validateConfiguration(launchpadConfiguration);
+
+            tasks.add(createTask(launchpadConfiguration, env));
+        }
+
+        // create the launchpad runner properties
+        this.createLaunchpadRunnerProperties(configurations);
+
+        if (parallelExecution) {
+            // ExecutorService for starting launchpad instances in parallel
+            final ExecutorService executor = Executors.newCachedThreadPool();
+            try {
+                final List<Future<ProcessDescription>> resultsCollector = executor.invokeAll(tasks);
+                for (final Future<ProcessDescription> future : resultsCollector) {
+                    try {
+                        if (null == future.get()) {
+                            throw new MojoExecutionException("Cannot start all the instances");
+                        }
+                    } catch (final ExecutionException e) {
+                        throw new MojoExecutionException(e.getLocalizedMessage(), e);
+                    }
+                }
+            } catch ( final InterruptedException e) {
+                throw new MojoExecutionException(e.getLocalizedMessage(), e);
+            }
+        } else {
+            for (final LauncherCallable task : tasks) {
+                try {
+                    if (null == task.call()) {
+                        throw new MojoExecutionException("Cannot start all the instances");
+                    }
+                } catch (final Exception e) {
+                    throw new MojoExecutionException(e.getLocalizedMessage(), e);
+                }
+            }
+        }
+        if (this.keepLaunchpadRunning) {
+            getLog().info("Press CTRL-C to stop launchpad instance(s)...");
+            while ( true && this.isRunning(tasks)) {
+                try {
+                    Thread.sleep(5000);
+                } catch (final InterruptedException ie) {
+                    break;
+                }
+            }
+        }
+        blockIfNecessary();
+    }
+
+    /**
+     * Are all launchpads still running?
+     */
+    private boolean isRunning(final Collection<LauncherCallable> tasks) {
+        for(final LauncherCallable task : tasks) {
+            if ( !task.isRunning() ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void createLaunchpadRunnerProperties(final Collection<ServerConfiguration> configurations)
+    throws MojoExecutionException {
+        // create properties
+        OutputStream writer = null;
+        final Properties props = new Properties();
+        try {
+            writer = new FileOutputStream(this.systemPropertiesFile);
+
+            // disable sling startup check
+            props.put("launchpad.skip.startupcheck", "true");
+
+            // write out all instances
+            int index = 0;
+            for (final ServerConfiguration launchpadConfiguration : configurations) {
+                index++;
+                props.put("launchpad.instance.id." + String.valueOf(index), launchpadConfiguration.getId());
+                String runMode = launchpadConfiguration.getRunmode();
+                if ( runMode == null ) {
+                    runMode = "";
+                }
+                props.put("launchpad.instance.runmode." + String.valueOf(index), runMode);
+                props.put("launchpad.instance.server." + String.valueOf(index), launchpadConfiguration.getServer());
+                props.put("launchpad.instance.port." + String.valueOf(index), launchpadConfiguration.getPort());
+                props.put("launchpad.instance.contextPath." + String.valueOf(index), launchpadConfiguration.getContextPath());
+                final String url = createServerUrl(launchpadConfiguration);
+                props.put("launchpad.instance.url." + String.valueOf(index), url);
+            }
+            props.put("launchpad.instances", String.valueOf(index));
+
+            props.store(writer, null);
+        } catch (final IOException e) {
+            throw new MojoExecutionException(e.getLocalizedMessage(), e);
+        } finally {
+            IOUtils.closeQuietly(writer);
+        }
+    }
+
+    private static String createServerUrl(final ServerConfiguration qc) {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("http://");
+        sb.append(qc.getServer());
+        if ( !qc.getPort().equals("80") ) {
+            sb.append(':');
+            sb.append(qc.getPort());
+        }
+        final String contextPath = qc.getContextPath();
+        if ( contextPath != null && contextPath.trim().length() > 0 && !contextPath.equals("/") ) {
+            if ( !contextPath.startsWith("/") ) {
+                sb.append('/');
+            }
+            if ( contextPath.endsWith("/") ) {
+                sb.append(contextPath, 0, contextPath.length()-1);
+            } else {
+                sb.append(contextPath);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * @param launchpadConfiguration
+     */
+    private LauncherCallable createTask(final ServerConfiguration launchpadConfiguration,
+                                               final LaunchpadEnvironment env)
+    throws MojoExecutionException, MojoFailureException {
+        final String id = launchpadConfiguration.getId();
+        getLog().debug(new StringBuilder("Starting ").append(id).
+                append(" with runmode ").append(launchpadConfiguration.getRunmode()).
+                append(" on port ").append(launchpadConfiguration.getPort()).
+                append(" in folder ").append(launchpadConfiguration.getFolder().getAbsolutePath()).toString());
+
+        // create task
+        return new LauncherCallable(this.getLog(), launchpadConfiguration, env);
+
+    }
+
+    /**
+     * Validate a configuration
+     * @param launchpadConfiguration The launchpad configuration
+     * @throws MojoExecutionException
+     */
+    private void validateConfiguration(final ServerConfiguration launchpadConfiguration)
+    throws MojoExecutionException {
+        if ( launchpadConfiguration.getPort() == null ) {
+            launchpadConfiguration.setPort(String.valueOf(PortHelper.getNextAvailablePort()));
+        }
+
+        if ( launchpadConfiguration.getControlPort() == null ) {
+            launchpadConfiguration.setControlPort(String.valueOf(PortHelper.getNextAvailablePort()));
+        }
+
+        // set the id of the launchpad
+        if ( launchpadConfiguration.getId() == null || launchpadConfiguration.getId().trim().length() == 0 ) {
+            String runMode = launchpadConfiguration.getRunmode();
+            if ( runMode == null ) {
+                runMode = "_";
+            }
+            final String id = new StringBuilder(runMode.replace(',', '_')).append('-').append(launchpadConfiguration.getPort()).toString();
+            launchpadConfiguration.setId(id);
+        }
+
+        // populate folder if not set
+        if (launchpadConfiguration.getFolder() == null) {
+            final File folder = new File(new StringBuilder(this.project.getBuild().getDirectory()).append('/').append(launchpadConfiguration.getId()).toString());
+            launchpadConfiguration.setFolder(folder);
+        }
+        // context path should not be null
+        if ( launchpadConfiguration.getContextPath() == null ) {
+            launchpadConfiguration.setContextPath("");
+        }
+
+        if ( launchpadConfiguration.getInstances() < 0 ) {
+            launchpadConfiguration.setInstances(1);
+        }
+    }
+
+    /**
+     * Finds the launchpad.jar artifact of the project being built.
+     *
+     * @return the launchpad.jar artifact
+     * @throws MojoFailureException if a launchpad.jar artifact was not found
+     */
+    private File findLaunchpadJar() throws MojoFailureException, MojoExecutionException {
+
+        // If a launchpad JAR is specified, use it
+        if (launchpadJar != null) {
+            getLog().info("Using launchpad jar from '" +  launchpadJar + "' given as configuration parameter!");
+            return launchpadJar;
+        }
+
+        // If a launchpad dependency is configured, resolve it
+        if (launchpadDependency != null) {
+            getLog().info("Using launchpad dependency '" +  launchpadDependency + "' given as configuration parameter!");
+            return getArtifact(launchpadDependency).getFile();
+        }
+
+        // If the current project is a slingstart project, use its JAR artifact
+        if (this.project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART)) {
+            File jarFile = project.getArtifact().getFile();
+            if (jarFile != null && jarFile.exists()) {
+                getLog().info("Using launchpad jar being generated as this project's primary artifact: '" +  jarFile + "'!");
+                return jarFile;
+            }
+            else {
+                jarFile = new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".jar");
+                if (jarFile.exists()) {
+                    getLog().info("Using launchpad jar being generated as this project's primary artifact: '" +  jarFile + "'!");
+                    return jarFile;
+                }
+            }
+        }
+
+        // In case there was a provisioning model found but this is not a slingstart project, the JAR might be attached already through goal "package"
+        for (Artifact attachedArtifact : project.getAttachedArtifacts()) {
+            // find the attached artifact with classifier "standalone"
+            if (BuildConstants.TYPE_JAR.equals(attachedArtifact.getType()) && BuildConstants.CLASSIFIER_APP.equals(attachedArtifact.getClassifier())) {
+                getLog().info("Using launchpad jar being attached as additional project artifact: '" +  attachedArtifact.getFile() + "'!");
+                return attachedArtifact.getFile();
+            }
+        }
+        
+        // also check for jars in known target folders (in case the jar has been created in this project's target folder but not attached to the Maven project)
+//AS TODO: Is Package Mojo still needed / supported ?
+//        File localJarFile = PackageMojo.getNonPrimaryBuildFile(project, ".jar");
+//        if (localJarFile.exists()) {
+//            getLog().info("Using local launchpad jar being created in predefined directory: '" +  localJarFile + "'!");
+//            return localJarFile;
+//        }
+        
+        // Last chance: use the first declared dependency with type "slingstart"
+        final Set<Artifact> dependencies = this.project.getDependencyArtifacts();
+        for (final Artifact dep : dependencies) {
+            if (BuildConstants.PACKAGING_SLINGSTART.equals(dep.getType())) {
+                final Dependency d = new Dependency();
+                d.setGroupId(dep.getGroupId());
+                d.setArtifactId(dep.getArtifactId());
+                d.setVersion(dep.getVersion());
+                d.setScope(Artifact.SCOPE_RUNTIME);
+                d.setType(BuildConstants.TYPE_JAR);
+                getLog().info("Using launchpad jar from first dependency of type 'slingstart': '"+ d +"'!");
+                return getArtifact(d).getFile();
+            }
+        }
+
+        // Launchpad has not been found, throw an exception
+        throw new MojoFailureException("Could not find the launchpad jar. " +
+                "Either specify the 'launchpadJar' configuration or use this inside a slingstart project.");
+    }
+
+    /**
+     * Get all configurations
+     * @return Collection of configurations.
+     */
+    private Collection<ServerConfiguration> getLaunchpadConfigurations() {
+        final List<ServerConfiguration> configs = new ArrayList<ServerConfiguration>();
+        if ( this.servers != null && !this.servers.isEmpty() ) {
+            for(final ServerConfiguration config : this.servers) {
+                // if instances is set to 0, no instance is added
+                if ( config.getInstances() != 0 ) {
+                    configs.add(config);
+                    for(int i=2; i<=config.getInstances();i++) {
+                        final ServerConfiguration replicaConfig = config.copy();
+                        replicaConfig.setPort(null);
+                        final File folder = replicaConfig.getFolder();
+                        if ( folder != null ) {
+                            replicaConfig.setFolder(new File(folder.getParentFile(), folder.getName() + '-' + String.valueOf(i)));
+                        }
+                        configs.add(replicaConfig);
+                    }
+                    config.setInstances(1);
+                }
+            }
+        } else {
+            // use single default instance
+            configs.add(new ServerConfiguration());
+        }
+        return configs;
+    }
+}
diff --git a/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java
new file mode 100644
index 0000000..213c729
--- /dev/null
+++ b/sling-slingstart-feature-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/feature/run/StopMojo.java
@@ -0,0 +1,88 @@
+/*
+ * 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.maven.slingstart.feature.run;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Stop one or multiple running launchpad instance(s).
+ *
+ */
+@Mojo(
+    name = "stop",
+    defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST,
+    threadSafe = true
+)
+public class StopMojo extends AbstractStartStopMojo {
+
+    @Override
+    protected void doExecute() throws MojoExecutionException, MojoFailureException {
+        
+        // read configurations
+        final Properties launchpadConfigProps = new Properties();
+        Reader reader = null;
+        try {
+            reader = new FileReader(this.systemPropertiesFile);
+            launchpadConfigProps.load(reader);
+        } catch ( final IOException ioe) {
+            throw new MojoExecutionException("Unable to read launchpad runner configuration properties.", ioe);
+        } finally {
+            IOUtils.closeQuietly(reader);
+        }
+
+        final int instances = Integer.valueOf(launchpadConfigProps.getProperty("launchpad.instances"));
+        final List<ProcessDescription> configurations = new ArrayList<ProcessDescription>();
+        for(int i=1;i<=instances;i++) {
+            final String id = launchpadConfigProps.getProperty("launchpad.instance.id." + String.valueOf(i));
+
+            final ProcessDescription config = ProcessDescriptionProvider.getInstance().getRunConfiguration(id);
+            if ( config == null ) {
+                getLog().warn("No launchpad configuration found for instance " + id);
+            } else {
+                configurations.add(config);
+            }
+        }
+
+        blockIfNecessary();
+        if (configurations.size() > 0) {
+            getLog().info(new StringBuilder("Stopping ").append(configurations.size()).append(" Launchpad instances").toString());
+
+            for (final ProcessDescription cfg : configurations) {
+
+                try {
+                    LauncherCallable.stop(this.getLog(), cfg);
+                    ProcessDescriptionProvider.getInstance().removeRunConfiguration(cfg.getId());
+                } catch (Exception e) {
+                    throw new MojoExecutionException("Could not stop launchpad " + cfg.getId(), e);
+                }
+            }
+        } else {
+            getLog().warn("No stored configuration file was found at " + this.systemPropertiesFile + " - no Launchapd will be stopped");
+        }
+    }
+}