Move this non-core project to Ace-extras.

git-svn-id: https://svn.apache.org/repos/asf/ace/trunk@1727269 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.ace.processlauncher/.classpath b/org.apache.ace.processlauncher/.classpath
deleted file mode 100644
index e3798ed..0000000
--- a/org.apache.ace.processlauncher/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" output="bin_test" path="test"/>
-    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
-	<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
-	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/org.apache.ace.processlauncher/.project b/org.apache.ace.processlauncher/.project
deleted file mode 100644
index b1a883e..0000000
--- a/org.apache.ace.processlauncher/.project
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.apache.ace.processlauncher</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>bndtools.core.bndbuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>bndtools.core.bndnature</nature>
-	</natures>
-</projectDescription>
diff --git a/org.apache.ace.processlauncher/bnd.bnd b/org.apache.ace.processlauncher/bnd.bnd
deleted file mode 100644
index fe67b12..0000000
--- a/org.apache.ace.processlauncher/bnd.bnd
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under the terms of ASLv2 (http://www.apache.org/licenses/LICENSE-2.0).
-
--buildpath: \
-	${^-buildpath},\
-	org.apache.felix.dependencymanager,\
-	org.mockito.mockito-all,\
-	osgi.core;version=6.0.0,\
-	osgi.cmpn,\
-	org.apache.ace.test;version=latest
-Private-Package: \
-	org.apache.ace.processlauncher.osgi,\
-	org.apache.ace.processlauncher.impl
-Bundle-Activator: \
-	org.apache.ace.processlauncher.osgi.Activator
-Export-Package: \
-	org.apache.ace.processlauncher,\
-	org.apache.ace.processlauncher.util
-Bundle-Version: 1.0.2
-Bundle-Name: Apache ACE ProcessLauncher
-Bundle-Description: Registers a service factory and ProcessLauncher service
\ No newline at end of file
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/LaunchConfiguration.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/LaunchConfiguration.java
deleted file mode 100644
index c1322ac..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/LaunchConfiguration.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher;
-
-import java.io.File;
-
-import aQute.bnd.annotation.ProviderType;
-
-/**
- * Denotes a particular launch configuration for a process, describing what and how to launch.
- * <p>
- * You can create a new launch configuration by "pushing" a new configuration to the ConfigAdmin
- * service. If you use something like Felix FileInstall, you can do this by creating a new
- * properties file with the following contents:
- * </p>
- * 
- * <pre>
- * # Denotes how many instances of the process should be started, >= 0.
- * # Optional, defaults to 1 instance.
- * #instance.count = 1
- * # What working directory should the executable start in?
- * # Optional, defaults to the current working directory.
- * #executable.workingDir = /path/to/cwd
- * # The executable to start, should be the fully qualified path to the
- * # executable.
- * # Mandatory, no default.
- * executable.name = /path/to/java
- * # The arguments for the executable.
- * # Mandatory, no default.
- * executable.args = -jar /path/to/jar
- * # The OSGi-filter clause which should resolve to a (single!)
- * # ProcessStreamListener instance. When given, it will be used to provide
- * # access to the launched process' stdin/stdout streams. NOTE: if you interact
- * # with the process this way, it could be that the process only terminates
- * # when you *explicitly* close the stdin stream.
- * # Optional, defaults to an empty/no filter.
- * #executable.processStreamListener =
- * # The OSGi-filter clause that should resolve to a ProcessLifecycleListener
- * # service-instance. When given, it will be used to provide hooks to when the
- * # executable is (re)started and stopped. 
- * # Optional, defaults to an empty/no filter.
- * #executable.processLifecycleListener = 
- * # When 'true' the process will automatically be restarted when it terminates
- * # with a 'abnormal' exit value (see 'executable.normalExitValue'). Any
- * # defined process stream listener will be re-invoked with the newly started
- * # process.
- * # Optional, defaults to 'false'.
- * #executable.respawnAutomatically = false
- * # Denotes what the 'normal' exit value of the process is, so the launcher can
- * # determine when a process is terminated abnormally.
- * # Optional, defaults to 0.
- * #executable.normalExitValue = 0
- * </pre>
- */
-@ProviderType
-public interface LaunchConfiguration {
-
-    /**
-     * Creates a fully qualified command line as array, in which the first element is the command to
-     * execute, and the remainder of the array consists of the arguments that are passed to the
-     * command.
-     * 
-     * @return the command line, as array, never <code>null</code>.
-     */
-    String[] getCommandLine();
-
-    /**
-     * Returns the optional arguments that should be passed to the executable.
-     * 
-     * @return the executable arguments, never <code>null</code>, but can be an empty array.
-     * @see #getExecutableName()
-     */
-    String[] getExecutableArgs();
-
-    /**
-     * Returns the full path-name to the executable to launch.
-     * 
-     * @return the executable name, never <code>null</code>.
-     */
-    String getExecutableName();
-
-    /**
-     * Returns the number of instances that should be launched.
-     * 
-     * @return an instance count, >= 1.
-     */
-    int getInstanceCount();
-
-    /**
-     * Returns the exit value that indicates whether or not the process is terminated
-     * successfully/normally. By convention, this is 0, but not all executables adhere to this
-     * convention.
-     * 
-     * @return the normal exit value, defaults to 0.
-     */
-    int getNormalExitValue();
-
-    /**
-     * Returns a filter-string to obtain the process' stream listener that wants to interact with
-     * the process.
-     * <p>
-     * Only a single process stream listener should be resolved by the returned filter condition.
-     * When multiple listeners are returned, the one with the highest service-ID will be used as
-     * defined in the OSGi specification.
-     * </p>
-     * 
-     * @return a OSGi-filter condition, or <code>null</code> (the default) if no interaction with
-     *         the process is desired.
-     */
-    String getProcessStreamListener();
-
-    /**
-     * Returns a filter-string to obtain the process' lifecycle listener that wants to get notified
-     * about the lifecycle of the process.
-     * <p>
-     * Only a single process lifecycle listener should be resolved by the returned filter condition.
-     * When multiple listeners are returned, the one with the highest service-ID will be used as
-     * defined in the OSGi specification.
-     * </p>
-     * 
-     * @return a OSGi-filter condition, or <code>null</code> (the default) if no notifications on
-     *         the process lifecycle are desired.
-     */
-    String getProcessLifecycleListener();
-
-    /**
-     * Returns the working directory to use when launching the executable.
-     * 
-     * @return a working directory, as {@link File} object, or <code>null</code> if no working
-     *         directory is to be set and the default should be used.
-     */
-    File getWorkingDirectory();
-
-    /**
-     * Returns whether the process should be respawned after it terminated with a non-zero exit
-     * code.
-     * 
-     * @return <code>true</code> if the process should be respawned when it terminates with a
-     *         non-zero exit code, <code>false</code> to leave it as-is (terminated).
-     */
-    boolean isRespawnAutomatically();
-
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLauncherService.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLauncherService.java
deleted file mode 100644
index 6729e84..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLauncherService.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher;
-
-import java.io.IOException;
-
-import aQute.bnd.annotation.ProviderType;
-
-/**
- * Provides a managed service factory for launching processes based on a certain launch
- * configuration.
- */
-@ProviderType
-public interface ProcessLauncherService {
-
-    /** The service PID that is used for registration of this service factory. */
-    String PID = "org.apache.ace.processlauncher";
-
-    /**
-     * Returns the number of launch configurations currently available.
-     * 
-     * @return the number of launch configurations, >= 0.
-     */
-    int getLaunchConfigurationCount();
-
-    /**
-     * Returns the number of running processes.
-     * 
-     * @return a running process count, >= 0.
-     * @throws IOException in case of I/O problems determining the number of running processes.
-     */
-    int getRunningProcessCount() throws IOException;
-
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLifecycleListener.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLifecycleListener.java
deleted file mode 100644
index 1a60001..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessLifecycleListener.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher;
-
-import java.util.Properties;
-
-import aQute.bnd.annotation.ConsumerType;
-
-/**
- * Allows code to be run <em>before</em> a process is actually launched, and <em>after</em> a
- * process is terminated.
- * <p>
- * A typical use case for this would be that you might want to set up some process-specific
- * directories and/or configuration files for each individually launched process.
- * </p>
- */
-@ConsumerType
-public interface ProcessLifecycleListener {
-
-    /**
-     * Called right before the process denoted by the given launch configuration is started.
-     * <p>
-     * Use this method to set up directories, or pre-process (provisioned) data/configuration files
-     * or other actions that need to be done in order to get the process properly up and running.
-     * </p>
-     * <p>
-     * This method can also adjust the environment of the to-be-created process by returning a
-     * populated {@link Properties} object.
-     * </p>
-     * 
-     * @param configuration the launch configuration of the process that is about to start, never
-     *        <code>null</code>.
-     * @return the environment properties of the to-be-created process. Can be <code>null</code> if
-     *         no additional environment settings are wanted/desired.
-     */
-    Properties beforeProcessStart(LaunchConfiguration configuration);
-
-    /**
-     * Called right after the process denoted by the given launch configuration is terminated.
-     * <p>
-     * Use this method to clean up directories.
-     * </p>
-     * 
-     * @param configuration the launch configuration of the process that is just terminated, never
-     *        <code>null</code>.
-     */
-    void afterProcessEnd(LaunchConfiguration configuration);
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessStreamListener.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessStreamListener.java
deleted file mode 100644
index 11b7b2a..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/ProcessStreamListener.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import aQute.bnd.annotation.ConsumerType;
-
-/**
- * Provides a listener interface for interacting with a process' input/output stream.
- */
-@ConsumerType
-public interface ProcessStreamListener {
-
-    /**
-     * Returns the process' input, as input stream to allow interaction with the process itself.
-     * <p>
-     * NOTE: if the given output stream is <strong>closed</strong> by the implementing code, the
-     * process will probably terminate. This also means that for some processes, you need to
-     * explicitly close the given stream in order to let the process terminate properly.
-     * </p>
-     * 
-     * @param launchConfiguration the launch configuration for which a stdin output stream is set,
-     *        cannot be <code>null</code>;
-     * @param outputStream the stdin {@link OutputStream} that can be used to write to the process'
-     *        stdin.
-     * @see #wantsStdin()
-     */
-    void setStdin(LaunchConfiguration launchConfiguration, OutputStream outputStream);
-
-    /**
-     * Called with the process' stdout {@link InputStream}.
-     * <p>
-     * NOTE: when not interacting with the given stream, strange and unpredictable behavior might
-     * occur, as the native streams that are used underneath the I/O streams in Java might
-     * overflow/block!<br/>
-     * Hence, <strong>always</strong> consume all bytes from this stream when implementing this
-     * method!
-     * </p>
-     * 
-     * @param launchConfiguration the launch configuration for which a stdout input stream is set,
-     *        cannot be <code>null</code>;
-     * @param inputStream the stdout {@link InputStream} that can be used to read from the process'
-     *        stdout and stderr.
-     * @see #wantsStdout()
-     */
-    void setStdout(LaunchConfiguration launchConfiguration, InputStream inputStream);
-
-    /**
-     * Returns whether or not the standard input of the process is desired by this listener.
-     * 
-     * @return <code>true</code> if the stdin {@link OutputStream} is to be set on this listener
-     *         (see {@link #setStdin(LaunchConfiguration, OutputStream)}), <code>false</code> if the
-     *         stdin {@link OutputStream} should be ignored.
-     */
-    boolean wantsStdin();
-
-    /**
-     * Returns whether or not the standard output of the process is desired by this listener.
-     * 
-     * @return <code>true</code> if the stdout {@link InputStream} is to be set on this listener
-     *         (see {@link #setStdout(LaunchConfiguration, InputStream)}), <code>false</code> if the
-     *         stdout {@link InputStream} should be redirected to '/dev/null'.
-     */
-    boolean wantsStdout();
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationFactory.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationFactory.java
deleted file mode 100644
index 869ab3f..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationFactory.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.ConfigurationException;
-
-/**
- * Provides a factory for creating new {@link LaunchConfiguration}s.
- */
-public abstract class LaunchConfigurationFactory {
-    /** Denotes the number of instances to start (defaults to 1). */
-    public static final String INSTANCE_COUNT = "instance.count";
-    /** Denotes the working directory to start from (defaults to the current working directory). */
-    public static final String WORKING_DIRECTORY = "executable.workingDir";
-    /** Denotes the executable to start (fully qualified pathname). */
-    public static final String EXECUTABLE_NAME = "executable.name";
-    /** Denotes the executable arguments (optional). */
-    public static final String EXECUTABLE_ARGS = "executable.args";
-    /** Denotes the filter-clause to obtain the process stream listener (optional). */
-    public static final String PROCESS_STREAM_LISTENER_FILTER = "executable.processStreamListener";
-    /** Denotes the filter-clause to obtain the process lifecycle listener (optional). */
-    public static final String PROCESS_LIFECYCLE_LISTENER_FILTER = "executable.processLifecycleListener";
-    /**
-     * Denotes whether or not the executable should be restarted upon unexpected termination
-     * (defaults to false).
-     */
-    public static final String RESPAWN_AUTOMATICALLY = "executable.respawnAutomatically";
-    /** Denotes the exit value that is to be considered normal (defaults to 0). */
-    public static final String NORMAL_EXIT_VALUE = "executable.normalExitValue";
-
-    /** The minimal instance count; less than one has no sense. */
-    private static final int MINIMAL_INSTANCE_COUNT = 1;
-
-    /**
-     * Creates a new {@link LaunchConfigurationFactory} instance, never used.
-     */
-    private LaunchConfigurationFactory() {
-        // No-op
-    }
-
-    /**
-     * Creates a new {@link LaunchConfiguration} instance.
-     * 
-     * @param config the configuration to create a {@link LaunchConfiguration} for, cannot be
-     *        <code>null</code>.
-     * @return a new {@link LaunchConfiguration} instance based on the information in the given
-     *         configuration, never <code>null</code>.
-     * @throws ConfigurationException in case the given configuration contains invalid keys and/or
-     *         values.
-     */
-    public static LaunchConfiguration create(final Dictionary<Object, Object> config) throws ConfigurationException {
-        if (config == null) {
-            throw new IllegalArgumentException("Config cannot be null!");
-        }
-
-        // Sanity check; make sure all mandatory properties are available...
-        checkMandatoryProperties(config, EXECUTABLE_ARGS, EXECUTABLE_NAME);
-
-        int instanceCount = 1;
-        String workingDirectory = null;
-        String executableName = null;
-        String[] executableArgs = null;
-        int normalExitValue = 0;
-        String processStreamListenerFilter = null;
-        String processLifecycleListenerFilter = null;
-        boolean respawnAutomatically = false;
-
-        Enumeration<Object> keys = config.keys();
-        while (keys.hasMoreElements()) {
-            Object key = keys.nextElement();
-            String value = String.valueOf(config.get(key)).trim();
-
-            if (INSTANCE_COUNT.equals(key)) {
-                instanceCount = parseInstanceCount(value);
-            }
-            else if (WORKING_DIRECTORY.equals(key)) {
-                workingDirectory = value.isEmpty() ? null : value;
-            }
-            else if (EXECUTABLE_NAME.equals(key)) {
-                executableName = parseExecutableName(value);
-            }
-            else if (EXECUTABLE_ARGS.equals(key)) {
-                executableArgs = parseExecutableArguments(value);
-            }
-            else if (PROCESS_STREAM_LISTENER_FILTER.equals(key)) {
-                processStreamListenerFilter = parseFilter(value);
-            }
-            else if (PROCESS_LIFECYCLE_LISTENER_FILTER.equals(key)) {
-                processLifecycleListenerFilter = parseFilter(value);
-            }
-            else if (RESPAWN_AUTOMATICALLY.equals(key)) {
-                respawnAutomatically = Boolean.parseBoolean(value);
-            }
-            else if (NORMAL_EXIT_VALUE.equals(key)) {
-                normalExitValue = parseExitValue(value);
-            }
-        }
-
-        return new LaunchConfigurationImpl(instanceCount, workingDirectory, executableName, executableArgs,
-            normalExitValue, processStreamListenerFilter, processLifecycleListenerFilter, respawnAutomatically);
-    }
-
-    /**
-     * Tests whether all mandatory properties are available in a given configuration.
-     * 
-     * @param config the configuration to test for mandatory keys;
-     * @param mandatoryKeys the keys to check.
-     * @throws ConfigurationException in case one of the given keys is missing from the given
-     *         configuration.
-     */
-    private static void checkMandatoryProperties(final Dictionary<Object, Object> config, final String... mandatoryKeys)
-        throws ConfigurationException {
-        for (String key : mandatoryKeys) {
-            if (config.get(key) == null) {
-                throw new ConfigurationException(key, "Missing configuration property: " + key);
-            }
-        }
-    }
-
-    /**
-     * Parses the given value and splits it into a string array, taking care of quoted strings.
-     * 
-     * @param value the value to split to a string array.
-     * @return a string array, never <code>null</code>, but can be empty if the given value was
-     *         <code>null</code> or empty.
-     */
-    private static String[] parseExecutableArguments(final String value) {
-        if (value == null || value.trim().isEmpty()) {
-            return new String[0];
-        }
-        return StringSplitter.split(value);
-    }
-
-    /**
-     * Parses the given executable name to something sensible.
-     * 
-     * @param value the value to parse as executable name.
-     * @return the executable name, never <code>null</code>.
-     * @throws ConfigurationException in case the given value was <code>null</code> or empty.
-     */
-    private static String parseExecutableName(final String value) throws ConfigurationException {
-        if (value == null || value.trim().isEmpty()) {
-            throw new ConfigurationException(EXECUTABLE_NAME, "Invalid executable name!");
-        }
-        return value;
-    }
-
-    /**
-     * Parses the given string value as integer exit value.
-     * 
-     * @param value the string to parse as exit value, can be <code>null</code>.
-     * @return the integer representation of the given string.
-     * @throws ConfigurationException in case the given value is not an integer value, or is an
-     *         invalid value for instance counts.
-     */
-    private static int parseExitValue(String value) throws ConfigurationException {
-        try {
-            return Integer.parseInt(value);
-        }
-        catch (NumberFormatException exception) {
-            throw new ConfigurationException(NORMAL_EXIT_VALUE, "Invalid exit value!");
-        }
-    }
-
-    /**
-     * Parses the given value as OSGi {@link Filter}.
-     * 
-     * @param value the value to parse as filter, cannot be <code>null</code>.
-     * @return the given input value, if it is a valid filter condition.
-     * @throws ConfigurationException in case the given value consists of an invalid filter.
-     */
-    private static String parseFilter(String value) throws ConfigurationException {
-        try {
-            FrameworkUtil.createFilter(value);
-            return value;
-        }
-        catch (InvalidSyntaxException exception) {
-            throw new ConfigurationException(PROCESS_STREAM_LISTENER_FILTER, "Invalid filter syntax! Reason: "
-                + exception.getMessage());
-        }
-    }
-
-    /**
-     * Parses a given string value into a numeric instance count.
-     * 
-     * @param value the string to parse as instance count, can be <code>null</code>.
-     * @return the instance count.
-     * @throws ConfigurationException in case the given value is not an integer value, or is an
-     *         invalid value for instance counts.
-     */
-    private static int parseInstanceCount(final String value) throws ConfigurationException {
-        int instanceCount = -1;
-        try {
-            instanceCount = Integer.parseInt(value);
-        }
-        catch (NumberFormatException exception) {
-            // Ignore, will be picked up below...
-        }
-
-        if (instanceCount < MINIMAL_INSTANCE_COUNT) {
-            throw new ConfigurationException(INSTANCE_COUNT, "Invalid instance count!");
-        }
-        return instanceCount;
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationImpl.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationImpl.java
deleted file mode 100644
index 8519638..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/LaunchConfigurationImpl.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.io.File;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.ProcessLifecycleListener;
-import org.apache.ace.processlauncher.ProcessStreamListener;
-
-/**
- * Denotes a launch configuration, describing what and how a process should be launched.
- */
-public final class LaunchConfigurationImpl implements LaunchConfiguration {
-    /** The convention is to use zero as normal exit value. */
-    private static final int NORMAL_EXIT_VALUE = 0;
-
-    /**
-     * Denotes the number of instances that will be launched for this configuration.
-     */
-    private final int m_instanceCount;
-    /** Denotes the full path-name to the executable to launch. */
-    private final String m_executableName;
-    /** Denotes the arguments to pass to the executable. */
-    private final String[] m_executableArgs;
-    /**
-     * The process stream listener that should be called for interaction with the process.
-     */
-    private final String m_processStreamListenerFilter;
-    /**
-     * The process lifecycle listener that should be called for the lifecycle changes of the
-     * process.
-     */
-    private final String m_processLifecycleListenerFilter;
-    /** Whether or not we should respawn the process once it died. */
-    private final boolean m_respawnAutomatically;
-    /** Which directory should be set before launching the executable. */
-    private final File m_workingDirectory;
-    /**
-     * What exit-value is to be considered "normal" for this process? By convention, this is 0.
-     */
-    private final int m_normalExitValue;
-
-    /**
-     * Creates a new {@link LaunchConfigurationImpl} instance.
-     * 
-     * @param instanceCount the number of instances to launch, >= 1;
-     * @param workingDirectory the optional working directory to use, can be <code>null</code> if
-     *        the default working directory should be used;
-     * @param executableName the full path-name to the executable to launch, cannot be
-     *        <code>null</code> or empty;
-     * @param executableArgs the optional arguments to pass to the executable, can be
-     *        <code>null</code>;
-     * @param normalExitValue the "normal" exit value to determine whether or not the process has
-     *        terminated normally;
-     * @param processStreamListenerFilter denotes the filter to use to obtain the
-     *        {@link ProcessStreamListener} to redirect the process input/output to, can be
-     *        <code>null</code> if no interaction is desired;
-     * @param processLifecycleListenerFilter denotes the filter to use to obtain the
-     *        {@link ProcessLifecycleListener};
-     * @param respawnAutomatically <code>true</code> if the process should be respawned
-     *        automatically upon non-zero exit codes.
-     */
-    public LaunchConfigurationImpl(int instanceCount, String workingDirectory, String executableName,
-        String[] executableArgs, int normalExitValue, String processStreamListenerFilter,
-        String processLifecycleListenerFilter, boolean respawnAutomatically) {
-        if (instanceCount <= 0) {
-            throw new IllegalArgumentException("Invalid instance count!");
-        }
-        if (executableName == null || executableName.trim().isEmpty()) {
-            throw new IllegalArgumentException("Invalid executable name!");
-        }
-        if (executableArgs == null) {
-            throw new IllegalArgumentException("Invalid executable args!");
-        }
-        m_instanceCount = instanceCount;
-        m_workingDirectory =
-            (workingDirectory == null || workingDirectory.trim().isEmpty()) ? null : new File(workingDirectory);
-        m_executableName = executableName;
-        m_executableArgs = executableArgs;
-        m_normalExitValue = normalExitValue;
-        m_processStreamListenerFilter = processStreamListenerFilter;
-        m_processLifecycleListenerFilter = processLifecycleListenerFilter;
-        m_respawnAutomatically = respawnAutomatically;
-    }
-
-    /**
-     * Creates a new {@link LaunchConfigurationImpl} instance.
-     * 
-     * @param instanceCount the number of instances to launch, >= 1;
-     * @param executableName the full path-name to the executable to launch, cannot be
-     *        <code>null</code> or empty;
-     * @param executableArgs the optional arguments to pass to the executable, can be
-     *        <code>null</code>;
-     * @param processStreamListenerFilter denotes the filter to use to obtain the
-     *        {@link ProcessStreamListener} to redirect the process input/output to, can be
-     *        <code>null</code> if no interaction is desired;
-     * @param respawnAutomatically <code>true</code> if the process should be respawned
-     *        automatically upon non-zero exit codes.
-     */
-    public LaunchConfigurationImpl(int instanceCount, String executableName, String[] executableArgs,
-        String processStreamListenerFilter, boolean respawnAutomatically) {
-        this(instanceCount, null, executableName, executableArgs, NORMAL_EXIT_VALUE, processStreamListenerFilter, null,
-            respawnAutomatically);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String[] getCommandLine() {
-        int size = this.m_executableArgs.length;
-        String[] result = new String[1 + size];
-
-        result[0] = this.m_executableName;
-        if (size > 0) {
-            System.arraycopy(this.m_executableArgs, 0, result, 1, size);
-        }
-
-        return result;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String[] getExecutableArgs() {
-        return m_executableArgs;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getExecutableName() {
-        return m_executableName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getInstanceCount() {
-        return m_instanceCount;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getNormalExitValue() {
-        return m_normalExitValue;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public File getWorkingDirectory() {
-        return m_workingDirectory;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getProcessStreamListener() {
-        return m_processStreamListenerFilter;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getProcessLifecycleListener() {
-        return m_processLifecycleListenerFilter;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isRespawnAutomatically() {
-        return m_respawnAutomatically;
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncher.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncher.java
deleted file mode 100644
index b8324bb..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncher.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.ProcessLifecycleListener;
-import org.apache.ace.processlauncher.ProcessStreamListener;
-import org.apache.ace.processlauncher.util.InputStreamRedirector;
-
-/**
- * Denotes a service that can launch a <em>single</em> process and possibly allows interaction with
- * it.
- * <p>
- * If for a process multiple instances should be launched, multiple {@link ProcessLauncher}
- * instances should be created!
- * </p>
- * 
- * @author Jan Willem Janssen <janwillem.janssen@luminis.eu>
- */
-public class ProcessLauncher {
-
-    private final LaunchConfiguration m_launchConfiguration;
-
-    private volatile ProcessStreamListener m_processStreamListener;
-    private volatile ProcessLifecycleListener m_processLifecycleListener;
-    private volatile Process m_runningProcess;
-
-    private InputStreamRedirector m_processStdoutRedirector;
-    private InputStreamRedirector m_processStdinRedirector;
-
-    /**
-     * Creates a new {@link ProcessLauncher} instance which redirects all input/output of the
-     * running process to the given streams.
-     * 
-     * @param launchConfiguration the launch configuration to use, cannot be <code>null</code>;
-     * @throws IllegalArgumentException in case the given launch configuration was <code>null</code>
-     *         .
-     */
-    public ProcessLauncher(LaunchConfiguration launchConfiguration) {
-        if (launchConfiguration == null) {
-            throw new IllegalArgumentException("Launch configuration cannot be null!");
-        }
-        m_launchConfiguration = launchConfiguration;
-    }
-
-    /**
-     * Creates a new {@link ProcessLauncher} instance which redirects all input/output of the
-     * running process to the given streams.
-     * 
-     * @param launchConfiguration the launch configuration to use, cannot be <code>null</code>;
-     * @param processStreamListener the input stream to redirect the process input to, can be
-     *        <code>null</code>;
-     * @param processLifecycleListener the output stream to redirect the process output to, can be
-     *        <code>null</code> if the process output is not to be redirected.
-     * @throws IllegalArgumentException in case the given launch configuration was <code>null</code>
-     *         .
-     */
-    public ProcessLauncher(LaunchConfiguration launchConfiguration, ProcessStreamListener processStreamListener,
-        ProcessLifecycleListener processLifecycleListener) {
-        if (launchConfiguration == null) {
-            throw new IllegalArgumentException("Launch configuration cannot be null!");
-        }
-        m_launchConfiguration = launchConfiguration;
-        m_processStreamListener = processStreamListener;
-        m_processLifecycleListener = processLifecycleListener;
-    }
-
-    /**
-     * If the process is finished, returns its exit value.
-     * 
-     * @return the process' exit value, or <code>null</code> if the process is still running.
-     * @see #isAlive()
-     */
-    public Integer getExitValue() {
-        // runningProcess can only be null if #run() is not yet called!
-        if ((m_runningProcess == null) || isAlive()) {
-            return null;
-        }
-
-        return m_runningProcess.exitValue();
-    }
-
-    /**
-     * Returns the launch configuration for this process launcher.
-     * 
-     * @return the launch configuration, never <code>null</code>.
-     */
-    public LaunchConfiguration getLaunchConfiguration() {
-        return m_launchConfiguration;
-    }
-
-    /**
-     * Call to clean up the administration of this process launcher, and to invoke the proper
-     * lifecycle methods on any interested listener.
-     * 
-     * @throws IllegalStateException in case the process is still alive.
-     * @see #isAlive()
-     */
-    public void cleanup() throws IllegalStateException {
-        if (isAlive()) {
-            throw new IllegalStateException("Process is still alive; cannot clean up!");
-        }
-
-        if (m_processLifecycleListener != null) {
-            m_processLifecycleListener.afterProcessEnd(m_launchConfiguration);
-        }
-
-        closeProcessStreamRedirects();
-    }
-
-    /**
-     * Kills any running processes and updates the internal administration (even if the process is
-     * already killed).
-     */
-    public void kill() {
-        if (isAlive()) {
-            // This does a simple kill, which might be ignored by the running
-            // process. In such situations, you should want to do something like
-            // 'kill -9', but this is not easily done in Java (without doing
-            // nasty hacks; see for example:
-            // <http://stackoverflow.com/questions/4912282/java-tool-method-to-force-kill-a-child-process>).
-            m_runningProcess.destroy();
-
-            try {
-                // We don't care for the result...
-                waitForTermination();
-            }
-            catch (InterruptedException exception) {
-                exception.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Creates a new process from the contained launch configuration and starts it as a new
-     * {@link Process}. After this, it waits until the process is completed.
-     * 
-     * @throws IllegalStateException in case there is already a running process that is not yet
-     *         finished;
-     * @throws IOException if an I/O error occurs during the invocation of the process.
-     */
-    public void run() throws IllegalStateException, IOException {
-        if (isAlive()) {
-            throw new IllegalStateException("Process is still running & alive!");
-        }
-
-        Properties customEnv = null;
-        if (m_processLifecycleListener != null) {
-            customEnv = m_processLifecycleListener.beforeProcessStart(m_launchConfiguration);
-        }
-
-        final ProcessBuilder pb = createProcessBuilder(customEnv);
-
-        // Invoke the actual executable asynchronously...
-        m_runningProcess = pb.start();
-
-        // Make sure we don't overflow any native buffers...
-        redirectProcessStreams(m_runningProcess);
-    }
-
-    /**
-     * Waits until the process is terminated.
-     * 
-     * @return the exit value of the terminated process, or <code>null</code> if the process was
-     *         never started.
-     * @throws InterruptedException in case we're interrupted while waiting for the process to
-     *         terminate.
-     */
-    public final Integer waitForTermination() throws InterruptedException {
-        if (m_runningProcess != null) {
-            final int result = m_runningProcess.waitFor();
-
-            cleanup();
-
-            return result;
-        }
-        return null;
-    }
-
-    /**
-     * Interrupts and closes all process stream redirects.
-     */
-    private void closeProcessStreamRedirects() {
-        // Make sure the redirectors are interrupted as well...
-        if (m_processStdinRedirector != null) {
-            try {
-                m_processStdinRedirector.join(1000);
-            }
-            catch (InterruptedException exception) {
-                exception.printStackTrace();
-            }
-            m_processStdinRedirector = null;
-        }
-        if (m_processStdoutRedirector != null) {
-            try {
-                m_processStdoutRedirector.join(1000);
-            }
-            catch (InterruptedException exception) {
-                exception.printStackTrace();
-            }
-            m_processStdoutRedirector = null;
-        }
-    }
-
-    /**
-     * Creates the process builder and ensures all of its settings are correct to be launched.
-     * 
-     * @param customEnv the custom environment settings of the to-be-created process, can be
-     *        <code>null</code> if no additional environment settings are desired.
-     * @return a {@link ProcessBuilder} instance, never <code>null</code>.
-     */
-    private ProcessBuilder createProcessBuilder(Properties customEnv) {
-        ProcessBuilder pb = new ProcessBuilder(m_launchConfiguration.getCommandLine());
-        // Make sure we grab both stdout *and* stderr!
-        pb.redirectErrorStream(true /* redirectErrorStream */);
-        pb.directory(m_launchConfiguration.getWorkingDirectory());
-        // We do *not* override/set a new environment for this process. This can
-        // be easily done with shell scripting as well, if desired...
-        if (customEnv != null) {
-            Map<String, String> env = pb.environment();
-            for (Object obj : customEnv.keySet()) {
-                String key = (String) obj;
-                env.put(key, customEnv.getProperty(key));
-            }
-        }
-        return pb;
-    }
-
-    /**
-     * Factory method for creating a {@link InputStreamRedirector} instance that redirects the stdin
-     * of the given process to the contained input stream (if available).
-     * 
-     * @param process the {@link Process} to create the input stream redirector for, can be
-     *        <code>null</code>.
-     * @return an input stream redirector instance, never <code>null</code>.
-     */
-    private InputStreamRedirector createStdinRedirector(Process process) {
-        if (m_processStreamListener != null && m_processStreamListener.wantsStdin()) {
-            m_processStreamListener.setStdin(m_launchConfiguration, process.getOutputStream());
-        }
-        return null;
-    }
-
-    /**
-     * Factory method for creating a {@link InputStreamRedirector} instance that redirects the
-     * stdout of the given process to either the contained output stream, or to '/dev/null'.
-     * 
-     * @param process the {@link Process} to create the input stream redirector for, cannot be
-     *        <code>null</code>.
-     * @return an input stream redirector instance, never <code>null</code>.
-     */
-    private InputStreamRedirector createStdoutRedirector(Process process) {
-        if (m_processStreamListener != null && m_processStreamListener.wantsStdout()) {
-            m_processStreamListener.setStdout(m_launchConfiguration, process.getInputStream());
-
-            return null;
-        }
-        // Redirect to /dev/null!
-        return new InputStreamRedirector(process.getInputStream());
-    }
-
-    /**
-     * Returns an indication whether or not the process is still alive and running, or already
-     * terminated.
-     * 
-     * @return <code>true</code> if the process is still running, <code>false</code> otherwise.
-     */
-    private boolean isAlive() {
-        try {
-            if (m_runningProcess != null) {
-                // If the process is still alive it'll throw an exception...
-                m_runningProcess.exitValue();
-            }
-
-            // No longer alive...
-            return false;
-        }
-        catch (IllegalThreadStateException e) {
-            return true;
-        }
-    }
-
-    /**
-     * Redirects the stdin/stdout streams of the given process.
-     * 
-     * @param process the process to redirect the streams for, cannot be <code>null</code>.
-     */
-    private void redirectProcessStreams(Process process) {
-        m_processStdoutRedirector = createStdoutRedirector(process);
-        if (m_processStdoutRedirector != null) {
-            m_processStdoutRedirector.start();
-        }
-        m_processStdinRedirector = createStdinRedirector(process);
-        if (m_processStdinRedirector != null) {
-            m_processStdinRedirector.start();
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncherServiceImpl.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncherServiceImpl.java
deleted file mode 100644
index d9876d0..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessLauncherServiceImpl.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.ProcessLauncherService;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.log.LogService;
-
-/**
- * Provides a managed service factory for launching processes based on a certain launch
- * configuration.
- */
-public class ProcessLauncherServiceImpl implements ManagedServiceFactory, ProcessLauncherService {
-
-    private static final String NAME = "Launcher Service Factory";
-
-    /** Contains all current launch configurations. */
-    private final Map<String, LaunchConfiguration> m_launchConfigurations = new HashMap<String, LaunchConfiguration>();
-    /** Manages all running processes for us. */
-    private volatile ProcessManager m_processManager;
-    private volatile LogService m_logger;
-
-    /**
-     * Returns whether or not a given PID is contained as launch configuration.
-     * 
-     * @param pid the PID to test for, cannot be <code>null</code>.
-     * @return <code>true</code> if the given PID exists as launch configuration, <code>false</code>
-     *         otherwise.
-     */
-    public boolean containsPid(String pid) {
-        synchronized (m_launchConfigurations) {
-            return m_launchConfigurations.containsKey(pid);
-        }
-    }
-
-    /**
-     * Called when a launch configuration with the given PID is removed from the config-admin.
-     * 
-     * @param pid the service PID that is to be deleted, never <code>null</code>.
-     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
-     */
-    public final void deleted(final String pid) {
-        LaunchConfiguration oldLaunchConfig = null;
-
-        synchronized (m_launchConfigurations) {
-            oldLaunchConfig = m_launchConfigurations.remove(pid);
-        }
-
-        if (oldLaunchConfig != null) {
-            terminateProcesses(pid, oldLaunchConfig);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getLaunchConfigurationCount() {
-        synchronized (m_launchConfigurations) {
-            return m_launchConfigurations.size();
-        }
-    }
-
-    /**
-     * Returns the symbolic name for this service factory.
-     * 
-     * @return a symbolic name, never <code>null</code>.
-     * @see org.osgi.service.cm.ManagedServiceFactory#getName()
-     */
-    public final String getName() {
-        return NAME;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getRunningProcessCount() throws IOException {
-        if (m_processManager == null) {
-            return 0;
-        }
-        return m_processManager.getRunningProcessesCount();
-    }
-
-    /**
-     * Sets the logging service.
-     * 
-     * @param logger the log service to set, can be <code>null</code>.
-     */
-    public void setLogger(LogService logger) {
-        m_logger = logger;
-    }
-
-    /**
-     * Sets the process manager.
-     * 
-     * @param processManager the process manager to set, cannot be <code>null</code>.
-     */
-    public void setProcessManager(ProcessManager processManager) {
-        m_processManager = processManager;
-    }
-
-    /**
-     * Shuts down this service and terminates all running processes.
-     * 
-     * @throws IOException in case of problems shutting down processes.
-     */
-    public void shutdown() throws IOException {
-        synchronized (m_launchConfigurations) {
-            for (Map.Entry<String, LaunchConfiguration> entry : m_launchConfigurations.entrySet()) {
-                terminateProcesses(entry.getKey(), entry.getValue());
-            }
-            m_launchConfigurations.clear();
-        }
-        // Shut down the process manager as well...
-        m_processManager.shutdown();
-    }
-
-    /**
-     * Called when a new configuration is added, or when an existing configuration is updated.
-     * 
-     * @param pid the service PID that is added/updated, never <code>null</code>;
-     * @param config the service configuration that is added/updated, can be <code>null</code>.
-     * @throws ConfigurationException in case the given service configuration is incorrect.
-     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String,
-     *      java.util.Dictionary)
-     */
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public final void updated(final String pid, final Dictionary config) throws ConfigurationException {
-        LaunchConfiguration oldLaunchConfig = null;
-        LaunchConfiguration newLaunchConfig = null;
-
-        if (config != null) {
-            newLaunchConfig = createLaunchConfiguration(config);
-        }
-
-        synchronized (m_launchConfigurations) {
-            oldLaunchConfig = m_launchConfigurations.put(pid, newLaunchConfig);
-        }
-
-        if (oldLaunchConfig != null) {
-            terminateProcesses(pid, oldLaunchConfig);
-        }
-        if (newLaunchConfig != null) {
-            launchProcesses(pid, newLaunchConfig);
-        }
-    }
-
-    /**
-     * Converts the given properties to a complete launch configuration.
-     * 
-     * @param config the properties to convert to a launch configuration, cannot be
-     *        <code>null</code>.
-     * @return a {@link LaunchConfiguration} instance, never <code>null</code>.
-     * @throws ConfigurationException in case an invalid configuration property was found.
-     */
-    private LaunchConfiguration createLaunchConfiguration(final Dictionary<Object, Object> config)
-        throws ConfigurationException {
-        return LaunchConfigurationFactory.create(config);
-    }
-
-    /**
-     * Creates a process identifier based on the given identifier and value.
-     * 
-     * @param id the identifier part;
-     * @param value the value part.
-     * @return a process identifier, as String, never <code>null</code>.
-     */
-    private String createPID(final String id, int value) {
-        return String.format("%s-%d", id, value);
-    }
-
-    /**
-     * Executes a given launch configuration.
-     * 
-     * @param id the identifier of the launch configuration to execute, cannot be <code>null</code>
-     *        or empty;
-     * @param launchConfiguration the launch configuration to execute, cannot be <code>null</code>.
-     */
-    private void launchProcesses(final String id, final LaunchConfiguration launchConfiguration) {
-
-        int count = launchConfiguration.getInstanceCount();
-        while (count-- > 0) {
-            String pid = createPID(id, count);
-            try {
-                m_processManager.launch(pid, launchConfiguration);
-
-                m_logger.log(LogService.LOG_DEBUG, "Launched instance #" + count + " of process " + pid);
-            }
-            catch (IOException e) {
-                m_logger.log(LogService.LOG_WARNING, "Process failed to launch!", e);
-            }
-        }
-    }
-
-    /**
-     * Cleans up & terminates all processes of a given launch configuration.
-     * 
-     * @param id the identifier of the launch configuration to execute, cannot be <code>null</code>
-     *        or empty;
-     * @param launchConfiguration the launch configuration to clean up, cannot be <code>null</code>.
-     */
-    private void terminateProcesses(final String id, final LaunchConfiguration launchConfiguration) {
-
-        int count = launchConfiguration.getInstanceCount();
-        while (count-- > 0) {
-            String pid = createPID(id, count);
-            try {
-                m_processManager.terminate(pid);
-
-                m_logger.log(LogService.LOG_DEBUG, "Terminated instance #" + count + " of process " + pid);
-            }
-            catch (IOException e) {
-                m_logger.log(LogService.LOG_WARNING, "Process failed to terminate!", e);
-            }
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManager.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManager.java
deleted file mode 100644
index bc5d654..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManager.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.io.IOException;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-
-/**
- * Provides a process manager service, which is able to launch a process (or multiple processes).
- */
-public interface ProcessManager {
-
-    /**
-     * Returns the number of currently running processes.
-     * <p>
-     * As a side effect, all completed processes are removed from the internal administration.
-     * </p>
-     * 
-     * @return a running process count.
-     * @throws IOException in case of I/O problems.
-     */
-    int getRunningProcessesCount() throws IOException;
-
-    /**
-     * Launches a new process.
-     * 
-     * @param pid the PID of the process to launch, used for bookkeeping;
-     * @param launchConfiguration the launch configuration to use for the process to be launched.
-     * @throws IOException in case of I/O problems during the launch of the process.
-     */
-    void launch(final String pid, final LaunchConfiguration launchConfiguration) throws IOException;
-
-    /**
-     * Terminates all managed processes and shuts down this process manager.
-     * 
-     * @throws IOException in case of I/O problems during the launch of the process.
-     */
-    void shutdown() throws IOException;
-
-    /**
-     * Terminates a running process.
-     * 
-     * @param pid the PID of the process to terminate, used for bookkeeping.
-     * @throws IOException in case of I/O problems during the launch of the process.
-     */
-    void terminate(final String pid) throws IOException;
-
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManagerImpl.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManagerImpl.java
deleted file mode 100644
index 509ba06..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/ProcessManagerImpl.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.ProcessLifecycleListener;
-import org.apache.ace.processlauncher.ProcessStreamListener;
-import org.apache.felix.dm.Component;
-import org.apache.felix.dm.DependencyManager;
-import org.osgi.service.log.LogService;
-
-/**
- * Manager for launched processes.
- */
-public class ProcessManagerImpl implements ProcessManager {
-
-    private final Map<String, ProcessLauncher> m_runningProcesses;
-
-    private volatile DependencyManager m_dependencyManager;
-    private volatile ProcessStateUpdater m_reaper;
-    private volatile LogService m_logger;
-
-    /**
-     * Creates a new {@link ProcessManagerImpl} instance.
-     */
-    public ProcessManagerImpl() {
-        m_runningProcesses = new HashMap<String, ProcessLauncher>();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int getRunningProcessesCount() throws IOException {
-        int result = 0;
-        synchronized (m_runningProcesses) {
-            updateAdministration();
-            result = m_runningProcesses.size();
-        }
-        return result;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void launch(final String pid, final LaunchConfiguration launchConfiguration) throws IOException {
-        // If this is the first time we're being called, make sure there's a
-        // reaper task up and running...
-        if (m_reaper == null || !m_reaper.isAlive()) {
-            m_reaper = new ProcessStateUpdater();
-            m_reaper.start();
-        }
-
-        // Create the process launcher service...
-        ProcessLauncher launcher = createProcessLauncher(launchConfiguration);
-
-        // Update our administration...
-        ProcessLauncher oldProcess = null;
-        synchronized (m_runningProcesses) {
-            oldProcess = m_runningProcesses.put(pid, launcher);
-        }
-
-        // Clean up any old processes...
-        killProcess(oldProcess);
-        // Submit it for execution...
-        launcher.run();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void shutdown() throws IOException {
-        synchronized (m_runningProcesses) {
-            // Cancel/kill all ongoing processes...
-            for (ProcessLauncher launcher : m_runningProcesses.values()) {
-                killProcess(launcher);
-            }
-            m_runningProcesses.clear();
-        }
-
-        if (m_reaper != null) {
-            m_reaper.interrupt();
-            try {
-                m_reaper.join();
-            }
-            catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-            }
-            finally {
-                m_reaper = null;
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void terminate(final String pid) {
-        ProcessLauncher launcher = null;
-        synchronized (m_runningProcesses) {
-            launcher = m_runningProcesses.remove(pid);
-        }
-        killProcess(launcher);
-    }
-
-    /**
-     * Updates the administration by cleaning up all future's that are finished.
-     * 
-     * @throws IOException in case of I/O problems.
-     */
-    final void updateAdministration() throws IOException {
-        synchronized (m_runningProcesses) {
-            List<String> pids = new ArrayList<String>(m_runningProcesses.keySet());
-            for (String pid : pids) {
-                ProcessLauncher launcher = m_runningProcesses.get(pid);
-                if (launcher.getExitValue() != null) {
-
-                    String logLine =
-                        String.format("Process %s (%s) terminated with code %d." + " Removing it from administration.",
-                            pid, launcher.getLaunchConfiguration().getExecutableName(), launcher.getExitValue());
-                    m_logger.log(LogService.LOG_DEBUG, logLine);
-
-                    launcher.cleanup();
-
-                    m_runningProcesses.remove(pid);
-                    // Take care of the termination; should it be relaunched?!
-                    if (processNeedsToBeRespawned(pid, launcher)) {
-                        launch(pid, launcher.getLaunchConfiguration());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Factory method for creating a {@link ProcessLauncher} instance.
-     * 
-     * @param launchConfiguration the launch configuration to create a launch configuration for,
-     *        cannot be <code>null</code>.
-     * @return a new {@link ProcessLauncher} instance, never <code>null</code>.
-     * @throws IOException in case the {@link ProcessLauncher} failed to instantiate.
-     */
-    private ProcessLauncher createProcessLauncher(LaunchConfiguration launchConfiguration) throws IOException {
-        ProcessLauncher processLauncher = new ProcessLauncher(launchConfiguration);
-
-        String lcFilter = launchConfiguration.getProcessLifecycleListener();
-        String psFilter = launchConfiguration.getProcessStreamListener();
-
-        // Create the proper service dependencies for the process launcher...
-        if (lcFilter != null || psFilter != null) {
-            Component comp = m_dependencyManager.createComponent().setImplementation(processLauncher);
-
-            if (psFilter != null) {
-                comp.add(m_dependencyManager.createServiceDependency()
-                    .setService(ProcessStreamListener.class, psFilter).setRequired(false));
-            }
-
-            if (lcFilter != null) {
-                comp.add(m_dependencyManager.createServiceDependency()
-                    .setService(ProcessLifecycleListener.class, lcFilter).setRequired(false));
-            }
-
-            m_dependencyManager.add(comp);
-        }
-
-        return processLauncher;
-    }
-
-    /**
-     * Determines whether or not the given exit value is "normal" indicating a successful or
-     * non-successful termination.
-     * 
-     * @param exitValue the process exit value, as integer value, can be <code>null</code>.
-     * @return <code>true</code> if the process is non-successfully terminated, <code>false</code>
-     *         if the processes terminated successfully.
-     */
-    private boolean isNonSuccessfullyTerminated(LaunchConfiguration config, Integer exitValue) {
-        return (exitValue != null) && (config.getNormalExitValue() != exitValue);
-    }
-
-    /**
-     * Cancels a given future, if it is not already completed its task.
-     * 
-     * @param launcher the process launcher to cancel, can be <code>null</code> in which case this
-     *        method does nothing.
-     */
-    private void killProcess(final ProcessLauncher launcher) {
-        if (launcher != null) {
-            String logLine =
-                String.format("Killing process (%s)...", launcher.getLaunchConfiguration().getExecutableName());
-            m_logger.log(LogService.LOG_INFO, logLine);
-
-            launcher.kill();
-        }
-    }
-
-    /**
-     * Handles a given terminated process, which might need to be relaunched if it is not cleanly
-     * terminated for example.
-     * 
-     * @param pid the PID of the process that was launched, cannot be <code>null</code>;
-     * @param launcher the terminated process to handle, cannot be <code>null</code>.
-     * @throws IOException in case of I/O problems during the respawn of a terminated process.
-     */
-    private boolean processNeedsToBeRespawned(String pid, ProcessLauncher launcher) throws IOException {
-        LaunchConfiguration config = launcher.getLaunchConfiguration();
-        Integer exitValue = launcher.getExitValue();
-
-        // Is the process non-successfully terminated?
-        if (isNonSuccessfullyTerminated(config, exitValue)) {
-            // If so, does it need to be respawned?
-            if (config.isRespawnAutomatically()) {
-                // We need to respawn the process automatically!
-                String logLine =
-                    String.format("Process %s (%s) terminated with value %d;" + " respawning it as requested...", pid,
-                        config.getExecutableName(), exitValue);
-                m_logger.log(LogService.LOG_INFO, logLine);
-
-                // Simply relaunch the process again...
-                return true;
-            }
-            else {
-                // Don't bother restarting the process...
-                String logLine =
-                    String.format("Process %s (%s) terminated with value %d.", pid, config.getExecutableName(),
-                        exitValue);
-                m_logger.log(LogService.LOG_INFO, logLine);
-            }
-        }
-        else {
-            // Process ended normally...
-            String logLine = String.format("Process %s (%s) terminated normally.", pid, config.getExecutableName());
-            m_logger.log(LogService.LOG_INFO, logLine);
-        }
-
-        return false;
-    }
-
-    /**
-     * Ensures that periodically the completed processes are removed from the administration.
-     */
-    final class ProcessStateUpdater extends Thread {
-        /**
-         * The number of milliseconds to wait before updating the status of all running processes.
-         */
-        private static final int DELAY = 100;
-
-        /**
-         * Creates a new {@link ProcessStateUpdater} instance.
-         */
-        public ProcessStateUpdater() {
-            super("Process state update thread");
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void run() {
-            while (!Thread.interrupted()) {
-                try {
-                    Thread.sleep(DELAY);
-
-                    m_logger.log(LogService.LOG_DEBUG, "Updating process administration...");
-
-                    // Update the administration...
-                    updateAdministration();
-                }
-                catch (InterruptedException e) {
-                    // Update the current thread's administration!
-                    Thread.currentThread().interrupt();
-                }
-                catch (IOException e) {
-                    m_logger.log(LogService.LOG_WARNING, "Respawn failed!", e);
-                }
-            }
-        }
-    }
-
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/StringSplitter.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/StringSplitter.java
deleted file mode 100644
index afeed41..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/impl/StringSplitter.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Splits a string on spaces and puts them into an array, taking care of single and double quotes.
- * Escaping quotes is allowed by prefixing them with a single backslash.
- */
-public final class StringSplitter {
-
-    private static final char ESCAPE = '\\';
-    private static final char SINGLE_QUOTE = '\'';
-    private static final char DOUBLE_QUOTE = '"';
-    private static final char SPACE = ' ';
-    private static final char TAB = '\t';
-
-    /**
-     * Creates a new StringSplitter instance, never used.
-     */
-    private StringSplitter() {
-        // No-op
-    }
-
-    /**
-     * Splits a given input on whitespace (= tabs and/or spaces). The backslash character can be
-     * used to escape stuff, for example to avoid splitting on certain spaces.
-     * 
-     * @param input the input to split, may be <code>null</code>.
-     * @return an empty array if the given input was <code>null</code> or empty, otherwise the split
-     *         results, never <code>null</code>.
-     */
-    public static String[] split(String input) {
-        return split(input, true /* includeQuotes */);
-    }
-
-    /**
-     * Splits a given input on whitespace (= tabs and/or spaces). The backslash character can be
-     * used to escape stuff, for example to avoid splitting on certain spaces.
-     * 
-     * @param input the input to split, may be <code>null</code>;
-     * @param includeQuotes <code>true</code> if quotes should be included in the output,
-     *        <code>false</code> to omit them in the output unless they are escaped.
-     * @return an empty array if the given input was <code>null</code> or empty, otherwise the split
-     *         results, never <code>null</code>.
-     */
-    public static String[] split(String input, boolean includeQuotes) {
-        if (input == null || input.trim().isEmpty()) {
-            return new String[0];
-        }
-
-        List<String> result = new ArrayList<String>();
-
-        State state = State.NORMAL;
-        boolean escapeSeen = false;
-        StringBuilder token = new StringBuilder();
-
-        for (int i = 0; i < input.length(); i++) {
-            char ch = input.charAt(i);
-
-            switch (ch) {
-                case ESCAPE:
-                    if (!escapeSeen) {
-                        escapeSeen = true;
-                    }
-                    else {
-                        // Escaped escape character...
-                        token.append(ch);
-                        escapeSeen = false;
-                    }
-                    break;
-
-                case SINGLE_QUOTE:
-                case DOUBLE_QUOTE:
-                    if (!escapeSeen) {
-                        if ((ch == DOUBLE_QUOTE && state.isInDoubleQuote())
-                            || (ch == SINGLE_QUOTE && state.isInSingleQuote())) {
-                            state = State.NORMAL;
-                        }
-                        else if (state.isNormal()) {
-                            state = (ch == DOUBLE_QUOTE) ? State.IN_DOUBLE_QUOTE : State.IN_SINGLE_QUOTE;
-                        }
-                    }
-                    if (includeQuotes) {
-                        token.append(ch);
-                    }
-                    escapeSeen = false;
-                    break;
-
-                case SPACE:
-                case TAB:
-                    if (state.isNormal() && !escapeSeen) {
-                        // Whitespace seen: emit a new token and start over...
-                        result.add(token.toString());
-                        token.setLength(0);
-                        break;
-                    }
-                    // Fallthrough!
-                default:
-                    token.append(ch);
-                    escapeSeen = false;
-                    break;
-            }
-        }
-
-        if (token.length() > 0) {
-            result.add(token.toString());
-        }
-
-        return result.toArray(new String[result.size()]);
-    }
-
-    private static enum State {
-        NORMAL, IN_SINGLE_QUOTE, IN_DOUBLE_QUOTE;
-
-        public boolean isInDoubleQuote() {
-            return this == IN_DOUBLE_QUOTE;
-        }
-
-        public boolean isInSingleQuote() {
-            return this == IN_SINGLE_QUOTE;
-        }
-
-        public boolean isNormal() {
-            return this == NORMAL;
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/osgi/Activator.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/osgi/Activator.java
deleted file mode 100644
index 3628b3a..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/osgi/Activator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.osgi;
-
-import java.util.Properties;
-
-import org.apache.ace.processlauncher.ProcessLauncherService;
-import org.apache.ace.processlauncher.impl.ProcessLauncherServiceImpl;
-import org.apache.ace.processlauncher.impl.ProcessManager;
-import org.apache.ace.processlauncher.impl.ProcessManagerImpl;
-import org.apache.felix.dm.DependencyActivatorBase;
-import org.apache.felix.dm.DependencyManager;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.log.LogService;
-
-/**
- * Provides the actual bundle activator (based on Felix Dependency Manager).
- */
-public class Activator extends DependencyActivatorBase {
-
-    private ProcessLauncherServiceImpl m_processLauncherService;
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
-        m_processLauncherService.shutdown();
-        m_processLauncherService = null;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void init(BundleContext context, DependencyManager manager) throws Exception {
-        // In the future we might want to publish this as an external service...
-        ProcessManager processManager = new ProcessManagerImpl();
-
-        manager.add(createComponent().setImplementation(processManager).add(
-            createServiceDependency().setService(LogService.class).setRequired(false)));
-
-        // We publish the service under multiple interfaces...
-        String[] interfaces = { ManagedServiceFactory.class.getName(), ProcessLauncherService.class.getName() };
-
-        // Service properties
-        Properties props = new Properties();
-        props.put(Constants.SERVICE_PID, ProcessLauncherService.PID);
-
-        m_processLauncherService = new ProcessLauncherServiceImpl();
-        m_processLauncherService.setProcessManager(processManager);
-
-        manager.add(createComponent().setInterface(interfaces, props).setImplementation(m_processLauncherService)
-            .add(createServiceDependency().setService(LogService.class).setRequired(false)));
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/packageinfo b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/InputStreamRedirector.java b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/InputStreamRedirector.java
deleted file mode 100644
index 4c71c50..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/InputStreamRedirector.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-/**
- * Redirects an {@link InputStream} by reading all of its contents and writing this to a given
- * {@link OutputStream}.
- */
-public class InputStreamRedirector extends Thread {
-
-    private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty(
-        "org.apache.ace.processlauncher.debug", "false"));
-
-    private static final int BUF_SIZE = 32;
-
-    private final InputStream m_inputStream;
-    private final OutputStream m_outputStream;
-
-    /**
-     * Creates a new {@link InputStreamRedirector} instance that redirects to /dev/null. Essentially
-     * this means that all read data is immediately thrown away.
-     * 
-     * @param inputStream the {@link InputStream} that is to be read, cannot be <code>null</code>.
-     */
-    public InputStreamRedirector(final InputStream inputStream) {
-        this(inputStream, null);
-    }
-
-    /**
-     * Creates a new {@link InputStreamRedirector} instance that redirects to a given output stream.
-     * 
-     * @param inputStream the {@link InputStream} that is to be redirected, cannot be
-     *        <code>null</code>;
-     * @param outputStream the {@link OutputStream} that is to be redirected to, may be
-     *        <code>null</code> in which case the input stream is redirected to nothing (/dev/null).
-     */
-    public InputStreamRedirector(final InputStream inputStream, final OutputStream outputStream) {
-        this.m_inputStream = inputStream;
-        this.m_outputStream = outputStream;
-
-        setName("InputStreamRedirector-" + getId());
-    }
-
-    /**
-     * Reads all bytes from the contained input stream and (optionally) writes it to the contained
-     * output stream.
-     */
-    @Override
-    public void run() {
-        try {
-            final byte[] buf = new byte[BUF_SIZE];
-
-            while (!Thread.currentThread().isInterrupted()) {
-                int read = m_inputStream.read(buf, 0, buf.length);
-                if (read < 0) {
-                    // EOF; break out of our main loop...
-                    break;
-                }
-
-                if (DEBUG) {
-                    System.out.write(buf, 0, read);
-                }
-
-                if (m_outputStream != null) {
-                    m_outputStream.write(buf, 0, read);
-                }
-            }
-        }
-        catch (IOException ioe) {
-            handleException(ioe);
-        }
-        finally {
-            cleanUp();
-        }
-    }
-
-    /**
-     * Clean up of the contained output stream by closing it properly.
-     */
-    private void cleanUp() {
-        try {
-            if (this.m_outputStream != null) {
-                // Ensure the last few bits are written...
-                this.m_outputStream.flush();
-                // Close the output stream and we're done...
-                this.m_outputStream.close();
-            }
-        }
-        catch (IOException e) {
-            // Ignore; we'll assume it is being handled elsewhere...
-        }
-    }
-
-    /**
-     * Handles the given I/O exception by either printing it to the contained output stream,
-     * otherwise to the stderr stream.
-     * 
-     * @param exception the exception to handle, cannot be <code>null</code>.
-     */
-    private void handleException(final IOException exception) {
-        if (this.m_outputStream != null) {
-            exception.printStackTrace(new PrintStream(this.m_outputStream));
-        }
-        else {
-            exception.printStackTrace(System.out);
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/packageinfo b/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/org.apache.ace.processlauncher/src/org/apache/ace/processlauncher/util/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationFactoryTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationFactoryTest.java
deleted file mode 100644
index b374c5f..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationFactoryTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.fail;
-
-import java.util.Properties;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.impl.LaunchConfigurationFactory;
-import org.osgi.service.cm.ConfigurationException;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link LaunchConfigurationFactory}.
- */
-public final class LaunchConfigurationFactoryTest {
-
-    private static void assertArrayEquals(Object[] expected, Object[] actual) {
-        assertEquals(expected.length, actual.length, "Array length mismatch!");
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], actual[i], "Array element (" + i + ") mismatch!");
-        }
-    }
-
-    /**
-     * Tests whether creating a launch configuration based on a properties file works correctly.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationBasedOnPropertiesFileOk() throws Exception {
-        Properties props = TestUtil.getProperties("launch.properties");
-        assertNotNull(props);
-
-        LaunchConfiguration config = LaunchConfigurationFactory.create(props);
-        assertNotNull(config);
-
-        assertEquals(2, config.getInstanceCount());
-        assertEquals("/bin/sh", config.getExecutableName());
-        assertArrayEquals(new String[] { "-c", "'sleep 1 && exit'", "-c", "'echo \"foo bar!\n\"'" },
-            config.getExecutableArgs());
-        assertNull(config.getProcessStreamListener());
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithCompleteConfigOk() throws ConfigurationException {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "(foo=bar)");
-        props.put(LaunchConfigurationFactory.RESPAWN_AUTOMATICALLY, "false");
-        props.put(LaunchConfigurationFactory.NORMAL_EXIT_VALUE, "2");
-
-        LaunchConfiguration config = LaunchConfigurationFactory.create(props);
-        assertNotNull(config);
-
-        assertEquals(1, config.getInstanceCount());
-        assertEquals("/path/to/foo", config.getExecutableName());
-        assertArrayEquals(new String[0], config.getExecutableArgs());
-        assertEquals(2, config.getNormalExitValue());
-        assertNotNull(config.getProcessStreamListener());
-        assertFalse(config.isRespawnAutomatically());
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithEmptyExecutableNameFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithInvalidInstanceCountFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "0");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithInvalidProcessStreamListenerFilterFail() throws ConfigurationException {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "aap"); // <=
-// incorrect!
-        props.put(LaunchConfigurationFactory.RESPAWN_AUTOMATICALLY, "false");
-        props.put(LaunchConfigurationFactory.NORMAL_EXIT_VALUE, "2");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException exception) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    public void testCreateWithNonNumericExitValueFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-        props.put(LaunchConfigurationFactory.NORMAL_EXIT_VALUE, "foo");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithNonNumericInstanceCountFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that a null configuration cannot be given to this factory.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithNullConfigFail() throws ConfigurationException {
-        try {
-            LaunchConfigurationFactory.create(null);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithNullExecutableArgumentsFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithNullExecutableNameFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException e) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that an incomplete configuration causes an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateWithNullInstanceCountFail() {
-        Properties props = new Properties();
-        props.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        props.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        props.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "true");
-
-        try {
-            LaunchConfigurationFactory.create(props);
-            fail("Exception expected!");
-        }
-        catch (ConfigurationException expected) {
-            // Ok...
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationTest.java
deleted file mode 100644
index a965036..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/LaunchConfigurationTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.impl.LaunchConfigurationImpl;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link LaunchConfigurationImpl}.
- */
-public final class LaunchConfigurationTest {
-
-    /**
-     * Test that creating a valid {@link LaunchConfigurationImpl} works.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationOk() {
-        LaunchConfiguration launchConfig = new LaunchConfigurationImpl(1, "/path/to/foo", new String[0], null, false);
-        assertNotNull(launchConfig);
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl} constructor validates the executable name
-     * properly.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationWithEmptyExecutableNameFail() {
-        try {
-            new LaunchConfigurationImpl(1, "", new String[0], null, false);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl} constructor validates the instance count
-     * properly.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationWithNegativeInstanceCountFail() {
-        try {
-            new LaunchConfigurationImpl(-1, "/path/to/foo", new String[0], null, false);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl} constructor validates the executable arguments
-     * properly.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationWithNullExecutableArgsFail() {
-        try {
-            new LaunchConfigurationImpl(1, "/path/to/foo", null, null, false);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl} constructor validates the executable name
-     * properly.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationWithNullExecutableNameFail() {
-        try {
-            new LaunchConfigurationImpl(1, null, new String[0], null, false);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl} constructor validates the instance count
-     * properly.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateLaunchConfigurationWithZeroInstanceCountFail() {
-        try {
-            new LaunchConfigurationImpl(0, "/path/to/foo", new String[0], null, false);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl#getCommandLine()} method works properly when one
-     * executable arguments are given.
-     */
-    @Test(groups = { UNIT })
-    public void testGetCommandLineWithOneArgumentsOk() {
-        LaunchConfiguration launchConfig =
-            new LaunchConfigurationImpl(1, "/path/to/foo", new String[] { "-bar" }, null, false);
-
-        String[] commandLine = launchConfig.getCommandLine();
-        assertNotNull(commandLine);
-        assertEquals(2, commandLine.length);
-
-        assertEquals("/path/to/foo", commandLine[0]);
-        assertEquals("-bar", commandLine[1]);
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl#getCommandLine()} method works properly when no
-     * executable arguments are given.
-     */
-    @Test(groups = { UNIT })
-    public void testGetCommandLineWithoutArgumentsOk() {
-        LaunchConfiguration launchConfig =
-            new LaunchConfigurationImpl(1, "cwd", "/path/to/foo", new String[0], 0, "(foo=bar)", "(qux=quu)", false);
-
-        String[] commandLine = launchConfig.getCommandLine();
-        assertNotNull(commandLine);
-        assertEquals(1, commandLine.length);
-
-        assertEquals("/path/to/foo", commandLine[0]);
-        assertEquals("cwd", launchConfig.getWorkingDirectory().getName());
-        assertNotNull(launchConfig.getProcessStreamListener());
-        assertFalse(launchConfig.isRespawnAutomatically());
-    }
-
-    /**
-     * Test that the {@link LaunchConfigurationImpl#getCommandLine()} method works properly when two
-     * executable arguments are given.
-     */
-    @Test(groups = { UNIT })
-    public void testGetCommandLineWithTwoArgumentsOk() {
-        LaunchConfiguration launchConfig =
-            new LaunchConfigurationImpl(1, "/path/to/foo", new String[] { "-qux", "-bar" }, null, true);
-
-        String[] commandLine = launchConfig.getCommandLine();
-        assertNotNull(commandLine);
-        assertEquals(3, commandLine.length);
-
-        assertEquals("/path/to/foo", commandLine[0]);
-        assertEquals("-qux", commandLine[1]);
-        assertEquals("-bar", commandLine[2]);
-        assertNull(launchConfig.getProcessStreamListener());
-        assertTrue(launchConfig.isRespawnAutomatically());
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherServiceImplTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherServiceImplTest.java
deleted file mode 100644
index 34e4821..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherServiceImplTest.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Dictionary;
-import java.util.Properties;
-
-import org.apache.ace.processlauncher.impl.LaunchConfigurationFactory;
-import org.apache.ace.processlauncher.impl.ProcessLauncherServiceImpl;
-import org.apache.ace.processlauncher.impl.ProcessManager;
-import org.apache.ace.processlauncher.impl.ProcessManagerImpl;
-import org.apache.ace.test.utils.TestUtils;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.log.LogService;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link ProcessLauncherServiceImpl}.
- */
-public class ProcessLauncherServiceImplTest {
-
-    private ProcessLauncherServiceImpl m_service;
-    private Dictionary<Object, Object> m_launchConfig;
-
-    /**
-     * Tests that adding/inserting a new launch configuration causes a configuration entry to be
-     * created.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testAddConfigurationWorksOk() throws ConfigurationException {
-        final String pid = "existing-pid";
-
-        assertEquals(0, m_service.getLaunchConfigurationCount());
-
-        m_service.updated(pid, m_launchConfig);
-        assertEquals(1, m_service.getLaunchConfigurationCount());
-    }
-
-    /**
-     * Tests that deleting an existing launch configuration works & doesn't cause an exception.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testDeleteExistingConfigurationOk() throws ConfigurationException {
-        final String pid = "existing-pid";
-
-        m_service.updated(pid, m_launchConfig);
-        assertTrue(m_service.containsPid(pid));
-
-        m_service.deleted(pid);
-        assertFalse(m_service.containsPid(pid));
-    }
-
-    /**
-     * Tests that deleting a non-existing launch configuration doesn't cause an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testDeleteNonExistingConfigurationOk() {
-        m_service.deleted("non-existing-pid");
-    }
-
-    /**
-     * Tests that the getName method doesn't return <code>null</code>.
-     */
-    @Test(groups = { UNIT })
-    public void testGetNameOk() {
-        assertNotNull(m_service.getName());
-    }
-
-    /**
-     * Tests the running process count is obtained from the (mocked) process manager.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testGetRunningProcessCountOk() throws Exception {
-        final String pid = "existing-pid";
-
-        m_service.updated(pid, m_launchConfig);
-        assertEquals(2, m_service.getRunningProcessCount());
-    }
-
-    /**
-     * Tests that updating an existing launch configuration cause the original configuration entry
-     * to be updated.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testReplacingConfigurationWorksOk() throws ConfigurationException {
-        final String pid = "existing-pid";
-
-        assertEquals(0, m_service.getLaunchConfigurationCount());
-
-        m_service.updated(pid, m_launchConfig);
-        assertEquals(1, m_service.getLaunchConfigurationCount());
-
-        m_service.updated(pid, m_launchConfig);
-        assertEquals(1, m_service.getLaunchConfigurationCount());
-    }
-
-    /**
-     * Tests that all existing launch configurations are removed when the service shutdown method is
-     * called.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testShutdownRemovesAllConfigurationsOk() throws Exception {
-        assertEquals(0, m_service.getLaunchConfigurationCount());
-
-        m_service.updated("pid1", m_launchConfig);
-        m_service.updated("pid2", m_launchConfig);
-
-        assertEquals(2, m_service.getLaunchConfigurationCount());
-
-        m_service.shutdown();
-
-        assertEquals(0, m_service.getLaunchConfigurationCount());
-    }
-
-    /**
-     * Tests that updating an existing launch configuration cause the original configuration entry
-     * to be updated.
-     * 
-     * @throws ConfigurationException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testUpdateConfigurationWorksOk() throws ConfigurationException {
-        final String pid = "existing-pid";
-
-        assertEquals(0, m_service.getLaunchConfigurationCount());
-
-        m_service.updated(pid, null);
-        assertEquals(1, m_service.getLaunchConfigurationCount());
-
-        m_service.updated(pid, m_launchConfig);
-        assertEquals(1, m_service.getLaunchConfigurationCount());
-    }
-
-    /**
-     * Set up for each test case.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @BeforeMethod
-    protected void setUp() throws Exception {
-        m_service = new ProcessLauncherServiceImpl();
-        m_service.setLogger(TestUtils.createNullObject(LogService.class));
-
-        ProcessManager processManager = mock(ProcessManagerImpl.class);
-        when(processManager.getRunningProcessesCount()).thenReturn(2);
-        m_service.setProcessManager(processManager);
-
-        m_launchConfig = new Properties();
-        m_launchConfig.put(LaunchConfigurationFactory.INSTANCE_COUNT, "1");
-        m_launchConfig.put(LaunchConfigurationFactory.EXECUTABLE_NAME, "/path/to/foo");
-        m_launchConfig.put(LaunchConfigurationFactory.EXECUTABLE_ARGS, "");
-        m_launchConfig.put(LaunchConfigurationFactory.PROCESS_STREAM_LISTENER_FILTER, "(foo=bar)");
-        m_launchConfig.put(LaunchConfigurationFactory.RESPAWN_AUTOMATICALLY, "false");
-        m_launchConfig.put(LaunchConfigurationFactory.NORMAL_EXIT_VALUE, "0");
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherTest.java
deleted file mode 100644
index 5b8a65e..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessLauncherTest.java
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.processlauncher.test.impl.TestUtil.getOSName;
-import static org.apache.ace.processlauncher.test.impl.TestUtil.sleep;
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Properties;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.ProcessLifecycleListener;
-import org.apache.ace.processlauncher.ProcessStreamListener;
-import org.apache.ace.processlauncher.impl.LaunchConfigurationImpl;
-import org.apache.ace.processlauncher.impl.ProcessLauncher;
-import org.apache.ace.processlauncher.util.InputStreamRedirector;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link ProcessLauncher}.
- */
-public class ProcessLauncherTest {
-
-    /**
-     * Tests that an existing executable (Java) can be called with valid arguments and its output
-     * can be read.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallAlreadyRunningProcessCausesExceptionFail() throws Exception {
-        String execName = determineJavaExecutable();
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(false /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-
-        try {
-            launcher.run(); // should fail!
-            fail("Exception expected!");
-        }
-        catch (IllegalStateException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that for a given {@link ProcessLifecycleListener} the lifecycle methods are called.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testLifecycleMethodsAreCalledOk() throws Exception {
-        String execName = determineJavaExecutable();
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(false /* wantsStdout */);
-        TestProcessLifecycleListener pll = new TestProcessLifecycleListener();
-
-        ProcessLauncher launcher = createProcessLauncher(psl, pll, execName);
-
-        launcher.run();
-
-        assertTrue(pll.m_beforeCalled);
-
-        // Will wait until process is finished and calls our lifecycle method...
-        launcher.waitForTermination();
-
-        assertTrue(pll.m_afterCalled);
-    }
-
-    /**
-     * Tests that calling {@link ProcessLauncher#cleanup()} will cause an exception if the process
-     * is not yet terminated.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallCleanupOnRunningProcessFails() throws Exception {
-        String execName = determineJavaExecutable();
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(false /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-
-        try {
-            launcher.cleanup(); // should fail!
-            fail("Exception expected!");
-        }
-        catch (IllegalStateException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that calling {@link ProcessLauncher#cleanup()} will cause no exception if the process
-     * is terminated.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallCleanupOnTerminatedProcessOk() throws Exception {
-        String execName = determineJavaExecutable();
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(false /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-
-        sleep(500);
-
-        launcher.cleanup();
-    }
-
-    /**
-     * Tests that an existing executable (Java) can be called with valid arguments and its output
-     * can be read.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallExistingExecutableWithoutArgumentOk() throws Exception {
-        String execName = determineJavaExecutable();
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(true /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-        Integer exitValue = launcher.waitForTermination();
-
-        assertNotNull(exitValue);
-        assertEquals(1, exitValue.intValue());
-        // Both methods should return the same exit value!
-        assertEquals(exitValue, launcher.getExitValue());
-
-        String stdout = psl.slurpStdout();
-        assertNotNull(stdout);
-        assertTrue(stdout.length() > 0);
-
-        // Make sure the test doesn't fail when the usage text is translated or
-        // something...
-        assertTrue(stdout.contains("Usage: java"), stdout);
-    }
-
-    /**
-     * Tests that an existing executable (Java) can be called with invalid arguments and its output
-     * can be read.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallExistingExecutableWithUnknownArgumentsOk() throws Exception {
-        String execName = determineJavaExecutable();
-        String execArgs = "-nonExistingArg";
-
-        ProcessLauncher launcher = createProcessLauncher(execName, execArgs);
-
-        launcher.run();
-        Integer exitValue = launcher.waitForTermination();
-
-        assertNotNull(exitValue);
-        assertFalse(0 == exitValue.intValue());
-        // Both methods should return the same exit value!
-        assertEquals(exitValue, launcher.getExitValue());
-    }
-
-    /**
-     * Tests that an existing executable (Java) can be called with valid arguments and its output
-     * can be read.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallExistingExecutableWithValidArgumentOk() throws Exception {
-        String execName = determineJavaExecutable();
-        String execArgs = "-version";
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(true /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName, execArgs);
-
-        launcher.run();
-        Integer exitValue = launcher.waitForTermination();
-
-        assertNotNull(exitValue);
-        assertEquals(0, exitValue.intValue());
-
-        String stdout = psl.slurpStdout();
-        assertNotNull(stdout);
-        assertTrue(stdout.length() > 0);
-
-        // Make sure the test doesn't fail when the usage text is translated or
-        // something...
-        assertTrue(stdout.contains("java version"), stdout);
-    }
-
-    /**
-     * Tests that an existing executable (Java) can be called and its output can be read.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testCallNonExistingExecutableOk() throws Exception {
-        String execName = "/path/to/java";
-        String execArgs = "-version";
-
-        ProcessLauncher launcher = createProcessLauncher(execName, execArgs);
-
-        try {
-            launcher.run(); // should fail!
-            fail("Exception expected!");
-        }
-        catch (IOException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that attempting to create a new {@link ProcessLauncher} without a valid launch
-     * configuration yields an exception.
-     */
-    @Test(groups = { UNIT })
-    public void testCreateProcessLauncherWithoutLaunchConfigurationFail() {
-        try {
-            new ProcessLauncher(null);
-            fail("Exception expected!");
-        }
-        catch (IllegalArgumentException expected) {
-            // Ok...
-        }
-    }
-
-    /**
-     * Tests that attempting to obtain the exit value without a launched process yields a null
-     * value.
-     */
-    @Test(groups = { UNIT })
-    public void testGetExitValueWithoutLaunchedProcessReturnsNull() {
-        String execName = determineJavaExecutable();
-        String execArgs = "-version";
-
-        ProcessLauncher launcher = createProcessLauncher(execName, execArgs);
-
-        assertNull(launcher.getExitValue());
-    }
-
-    /**
-     * Tests that we can send commands to a running process and capture the results of these
-     * commands.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testInteractWithProcessOk() throws Exception {
-        // Test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        String execName = "/bin/sh";
-        String input = "echo '1'\nls $0\nsleep 1\n";
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(true /* wantsStdin */, true /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-
-        psl.writeToStdin(input);
-        psl.closeStdin();
-
-        Integer exitValue = launcher.waitForTermination();
-
-        assertNotNull(exitValue);
-        assertEquals(0, exitValue.intValue());
-
-        String stdout = psl.slurpStdout();
-        assertNotNull(stdout);
-        assertTrue(stdout.length() > 0);
-
-        // Make sure the test doesn't fail when the usage text is translated or
-        // something...
-        assertEquals("1\n/bin/sh\n", stdout);
-    }
-
-    /**
-     * Tests that we can send commands to a running process and capture the results of these
-     * commands.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testInteractWithProcessThroughArgumentsOk() throws Exception {
-        // Test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        String execName = "/bin/sh";
-        String[] execArgs = { "-c", "echo '1'\nls $0\nsleep 1\n" };
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(false /* wantsStdin */, true /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName, execArgs);
-
-        launcher.run();
-
-        Integer exitValue = launcher.waitForTermination();
-
-        String stdout = psl.slurpStdout();
-        assertNotNull(stdout);
-        assertTrue(stdout.length() > 0);
-
-        assertNotNull(exitValue);
-        assertEquals(0, exitValue.intValue());
-
-        assertEquals("1\n/bin/sh\n", stdout);
-    }
-
-    /**
-     * Tests that we can send commands to a running cat-process and capture the results of these
-     * commands.
-     * <p>
-     * The cat-command is a somewhat "nasty" command as it won't exit until its input stream is
-     * properly closed.
-     * </p>
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testProcessStdinIsProperlyClosedOk() throws Exception {
-        // Test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        String execName = "/bin/cat";
-        String input = "echo '1'\nls $0\nqux qoo\n";
-
-        TestProcessStreamListener psl = new TestProcessStreamListener(true /* wantsStdin */, true /* wantsStdout */);
-
-        ProcessLauncher launcher = createProcessLauncher(psl, null, execName);
-
-        launcher.run();
-
-        // Issue the command...
-        psl.writeToStdin(input);
-
-        sleep(1000);
-
-        psl.closeStdin();
-
-        Integer exitValue = launcher.waitForTermination();
-
-        assertNotNull(exitValue);
-        assertEquals(0, exitValue.intValue());
-
-        String stdout = psl.slurpStdout();
-        assertNotNull(stdout);
-        assertTrue(stdout.length() > 0);
-
-        // We should get the exact same output as we've put into the command...
-        assertEquals(input, stdout);
-    }
-
-    /**
-     * Creates a new launch configuration for the given executable and arguments.
-     * 
-     * @param captureProcessOutput <code>true</code> if the process output is to be captured,
-     *        <code>false</code> otherwise;
-     * @param execName the name of the executable;
-     * @param execArgs the (optional) arguments.
-     * @return a {@link LaunchConfigurationImpl} instance, never <code>null</code>.
-     */
-    private LaunchConfiguration createLaunchConfiguration(boolean respawnAutomatically, String execName,
-        String... execArgs) {
-        return new LaunchConfigurationImpl(1, execName, execArgs, null, respawnAutomatically);
-    }
-
-    /**
-     * Creates a new process launcher instance for the given executable and arguments.
-     * 
-     * @param execName the name of the executable;
-     * @param execArgs the (optional) arguments.
-     * @return a {@link ProcessLauncher} instance, never <code>null</code>.
-     */
-    private ProcessLauncher createProcessLauncher(ProcessStreamListener processStreamListener,
-        ProcessLifecycleListener processLifecycleListener, String execName, String... execArgs) {
-        return new ProcessLauncher(createLaunchConfiguration(false, execName, execArgs), processStreamListener,
-            processLifecycleListener);
-    }
-
-    /**
-     * Creates a new process launcher instance for the given executable and arguments.
-     * 
-     * @param execName the name of the executable;
-     * @param execArgs the (optional) arguments.
-     * @return a {@link ProcessLauncher} instance, never <code>null</code>.
-     */
-    private ProcessLauncher createProcessLauncher(String execName, String... execArgs) {
-        return new ProcessLauncher(createLaunchConfiguration(false, execName, execArgs));
-    }
-
-    /**
-     * Returns the full path to the java executable (the one that is used to invoke this test).
-     * 
-     * @return a full path to the executable, never <code>null</code>.
-     */
-    private String determineJavaExecutable() {
-        StringBuilder sb = new StringBuilder(System.getProperty("java.home"));
-        sb.append(File.separatorChar).append("bin").append(File.separatorChar).append("java");
-        return sb.toString();
-    }
-
-    /**
-     * Test implementation of {@link ProcessLifecycleListener}.
-     * 
-     * @author jwjanssen
-     */
-    static final class TestProcessLifecycleListener implements ProcessLifecycleListener {
-        private volatile boolean m_beforeCalled;
-        private volatile boolean m_afterCalled;
-
-        /**
-         * {@inheritDoc}
-         */
-        public void afterProcessEnd(LaunchConfiguration configuration) {
-            m_afterCalled = true;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public Properties beforeProcessStart(LaunchConfiguration configuration) {
-            m_beforeCalled = true;
-            return null;
-        }
-    }
-
-    /**
-     * Provides a mock implementation of {@link ProcessStreamListener} that is used in the various
-     * test cases.
-     * 
-     * @author jwjanssen
-     */
-    static final class TestProcessStreamListener implements ProcessStreamListener {
-        private final boolean m_wantsStdin;
-        private final boolean m_wantsStdout;
-
-        private OutputStream m_stdin;
-        private OutputStream m_stdout;
-
-        public TestProcessStreamListener(boolean wantsStdout) {
-            this(false /* wantsStdin */, wantsStdout);
-        }
-
-        public TestProcessStreamListener(boolean wantsStdin, boolean wantsStdout) {
-            m_wantsStdin = wantsStdin;
-            m_wantsStdout = wantsStdout;
-        }
-
-        public synchronized void closeStdin() throws IOException {
-            m_stdin.flush();
-            m_stdin.close();
-        }
-
-        public void setStdin(LaunchConfiguration launchConfiguration, OutputStream outputStream) {
-            m_stdin = outputStream;
-        }
-
-        public void setStdout(LaunchConfiguration launchConfiguration, InputStream inputStream) {
-            m_stdout = new ByteArrayOutputStream(1024);
-            InputStreamRedirector isr = new InputStreamRedirector(inputStream, m_stdout);
-            isr.start();
-        }
-
-        public String slurpStdout() throws IOException {
-            assertNotNull(m_stdout);
-            m_stdout.flush();
-            return m_stdout.toString();
-        }
-
-        public boolean wantsStdin() {
-            return m_wantsStdin;
-        }
-
-        public boolean wantsStdout() {
-            return m_wantsStdout;
-        }
-
-        public void writeToStdin(String commands) throws IOException {
-            assertNotNull(m_stdin);
-            m_stdin.write(commands.getBytes());
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessManagerImplTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessManagerImplTest.java
deleted file mode 100644
index b55cf40..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/ProcessManagerImplTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.processlauncher.test.impl.TestUtil.createTempDir;
-import static org.apache.ace.processlauncher.test.impl.TestUtil.getOSName;
-import static org.apache.ace.processlauncher.test.impl.TestUtil.sleep;
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.io.File;
-
-import org.apache.ace.processlauncher.LaunchConfiguration;
-import org.apache.ace.processlauncher.impl.LaunchConfigurationImpl;
-import org.apache.ace.processlauncher.impl.ProcessManager;
-import org.apache.ace.processlauncher.impl.ProcessManagerImpl;
-import org.apache.ace.test.utils.TestUtils;
-import org.osgi.service.log.LogService;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link ProcessManager}.
- */
-public class ProcessManagerImplTest {
-    
-    private ProcessManagerImpl m_processManager;
-
-    /**
-     * Tests that launching a simple process works for a UNIX-derived operating system.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testLaunchProcessOnUnixDerivativeOk() throws Exception {
-        // This test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 1 && exit 1");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        m_processManager.launch("myPid", launchConfig);
-
-        // make sure we sleep a little to ensure the process is started
-        sleep(100);
-
-        int processCountAfter = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfter > processCountBefore);
-
-        assertEquals(processCountAfter, m_processManager.getRunningProcessesCount());
-
-        // make sure we sleep a little longer to allow the process to finish...
-        sleep(1000);
-
-        assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
-    }
-
-    /**
-     * Tests that launching a simple process works for a Windows operating system.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testLaunchProcessOnWindowsOk() throws Exception {
-        // This test will only work on Windows!
-        if (!getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "2", "127.0.0.1");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        m_processManager.launch("myPid", launchConfig);
-
-        // make sure we sleep a little to ensure the process is started
-        sleep(100);
-
-        int processCountAfter = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfter > processCountBefore);
-
-        assertEquals(processCountAfter, m_processManager.getRunningProcessesCount());
-
-        // make sure we sleep a little longer to allow the process to finish...
-        sleep(1000);
-
-        assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
-    }
-
-    /**
-     * Tests that respawning a simple process works for a UNIX-derived operating system.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testRespawnProcessOnUnixDerivativeOk() throws Exception {
-        // This test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        int count = 2;
-        File tmpFile = File.createTempFile("ace", null);
-        String tmpFilename = tmpFile.getAbsolutePath();
-
-        // Seems daunting, but what this command does is simply count the number
-        // of lines in a given file (= tmpFile), and append this to that same
-        // file; it uses this number to create an exit value, which counts from
-        // <count> back to 0. This way, we can test whether the respawn
-        // functionality works, as this currently checks for certain exit
-        // values...
-        String script =
-            String.format("L=$(cat %1$s | wc -l)" + "&& echo $L >> %1$s && exit $((%2$d-$L))", tmpFilename, count);
-
-        LaunchConfiguration launchConfig =
-            createLaunchConfiguration(true /* respawnAutomatically */, "/bin/bash", "-c", script);
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        m_processManager.launch("myPid", launchConfig);
-
-        // sleep a little to ensure the process is started...
-        sleep(10);
-
-        assertEquals(processCountBefore + 1, m_processManager.getRunningProcessesCount());
-
-        // make sure we sleep a little longer to allow the process to finish...
-        sleep(500);
-
-        assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
-
-        String testResult = TestUtil.slurpFile(tmpFile);
-        assertTrue(testResult.matches("(?s)^0\n1\n2\n$"), testResult);
-    }
-
-    /**
-     * Tests that terminating all running processes works.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testShutdownOnUnixDerivativeOk() throws Exception {
-        // This test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 10");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        for (int i = 0; i < 5; i++) {
-            m_processManager.launch(String.format("myPid%d", i), launchConfig);
-        }
-
-        // make sure we sleep a little to ensure the processes are started
-        sleep(100);
-
-        int processCountAfter = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfter > processCountBefore);
-
-        // Shut down the process manager; should terminate all running
-        // processes...
-        m_processManager.shutdown();
-
-        assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
-    }
-
-    /**
-     * Tests that terminating all running processes works.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testShutdownOnWindowsOk() throws Exception {
-        // This test will only work on Windows!
-        if (!getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "11", "127.0.0.1");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        for (int i = 0; i < 5; i++) {
-            m_processManager.launch(String.format("myPid%d", i), launchConfig);
-        }
-
-        // make sure we sleep a little to ensure the processes are started
-        sleep(100);
-
-        int processCountAfter = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfter > processCountBefore);
-
-        // Shut down the process manager; should terminate all running
-        // processes...
-        m_processManager.shutdown();
-
-        assertEquals(processCountBefore, m_processManager.getRunningProcessesCount());
-    }
-
-    /**
-     * Tests that terminating a single process works.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testTerminateProcessOnUnixDerivativeOk() throws Exception {
-        // This test will not work on Windows!
-        if (getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("/bin/sh", "-c", "sleep 10");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        final String pid = "myPid";
-        m_processManager.launch(pid, launchConfig);
-
-        // make sure we sleep a little to ensure the process is started
-        sleep(100);
-
-        int processCountAfterLaunch = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfterLaunch > processCountBefore);
-
-        m_processManager.terminate(pid);
-
-        int processCountAfterTerminate = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfterTerminate == processCountBefore);
-    }
-
-    /**
-     * Tests that terminating a single process works.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testTerminateProcessOnWindowsOk() throws Exception {
-        // This test will not work on Windows!
-        if (!getOSName().contains("windows")) {
-            return;
-        }
-
-        LaunchConfiguration launchConfig = createLaunchConfiguration("PING", "-n", "11", "127.0.0.1");
-
-        int processCountBefore = m_processManager.getRunningProcessesCount();
-
-        final String pid = "myPid";
-        m_processManager.launch(pid, launchConfig);
-
-        // make sure we sleep a little to ensure the process is started
-        sleep(100);
-
-        int processCountAfterLaunch = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfterLaunch > processCountBefore);
-
-        m_processManager.terminate(pid);
-
-        int processCountAfterTerminate = m_processManager.getRunningProcessesCount();
-
-        assertTrue(processCountAfterTerminate == processCountBefore);
-    }
-
-    /**
-     * Set up for this test case.
-     */
-    @BeforeTest
-    protected void setUp() {
-        m_processManager = new ProcessManagerImpl();
-        TestUtils.configureObject(m_processManager, LogService.class);
-    }
-
-    /**
-     * Creates a new launch configuration for the given executable and arguments.
-     * 
-     * @param respawnAutomatically <code>true</code> if the process should be respawned
-     *        automatically upon a non-zero exit value;
-     * @param execName the name of the executable;
-     * @param execArgs the (optional) arguments.
-     * 
-     * @return a {@link LaunchConfigurationImpl} instance, never <code>null</code>.
-     */
-    private LaunchConfiguration createLaunchConfiguration(boolean respawnAutomatically, String execName,
-        String... execArgs) throws Exception {
-        return new LaunchConfigurationImpl(1, createTempDir().getAbsolutePath(), execName, execArgs, 0, null /* processStreamListenerFilter */,
-            null /* processLifecycleListenerFilter */, respawnAutomatically);
-    }
-
-    /**
-     * Creates a new launch configuration for the given executable and arguments.
-     * 
-     * @param execName the name of the executable;
-     * @param execArgs the (optional) arguments.
-     * 
-     * @return a {@link LaunchConfigurationImpl} instance, never <code>null</code>.
-     */
-    private LaunchConfiguration createLaunchConfiguration(String execName, String... execArgs) throws Exception {
-        return createLaunchConfiguration(false /* respawnAutomatically */, execName, execArgs);
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/StringSplitterTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/StringSplitterTest.java
deleted file mode 100644
index 033a7f7..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/StringSplitterTest.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import static org.apache.ace.processlauncher.impl.StringSplitter.split;
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.testng.Assert.assertEquals;
-
-import org.apache.ace.processlauncher.impl.StringSplitter;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link StringSplitter}.
- */
-public class StringSplitterTest {
-
-    /**
-     * Test double quoted command line argument.
-     */
-    @Test(groups = { UNIT })
-    public void testDoubleQuotedCommandLineArgumentOk() {
-        String[] result =
-            split("\\\"fwOption=org.osgi.framework.system.packages.extra=org.w3c.dom.tral,org.w3c.dom.html,org.w3c.dom.ranges,sun.reflect,org.osgi.service.deploymentadmin;version=\"1.0\",org.osgi.service.deploymentadmin.spi;version=\"1.0\",org.osgi.service.cm;version=\"1.3\",org.osgi.service.event;version=\"1.2\",org.osgi.service.log;version=\"1.3\",org.osgi.service.metatype;version=\"1.1\",org.apache.ace.log;version=\"0.8.0\"\\\"");
-        assertArrayEquals(
-            new String[] { "\"fwOption=org.osgi.framework.system.packages.extra=org.w3c.dom.tral,org.w3c.dom.html,org.w3c.dom.ranges,sun.reflect,org.osgi.service.deploymentadmin;version=\"1.0\",org.osgi.service.deploymentadmin.spi;version=\"1.0\",org.osgi.service.cm;version=\"1.3\",org.osgi.service.event;version=\"1.2\",org.osgi.service.log;version=\"1.3\",org.osgi.service.metatype;version=\"1.1\",org.apache.ace.log;version=\"0.8.0\"\"" },
-            result);
-    }
-
-    /**
-     * Test double quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testDoubleQuotedStringOk() {
-        String[] result = split("\"hello world\"");
-        assertArrayEquals(new String[] { "\"hello world\"" }, result);
-    }
-
-    /**
-     * Test double quoted string with trailing text.
-     */
-    @Test(groups = { UNIT })
-    public void testDoubleQuotedStringWithTrailingTextOk() {
-        String[] result = split("\"hello world\" foo-bar");
-        assertArrayEquals(new String[] { "\"hello world\"", "foo-bar" }, result);
-    }
-
-    /**
-     * Test double quoted words.
-     */
-    @Test(groups = { UNIT })
-    public void testDoubleQuotedWordsOk() {
-        String[] result = split("\"hello\" \"world\"");
-        assertArrayEquals(new String[] { "\"hello\"", "\"world\"" }, result);
-    }
-
-    /**
-     * Test double quoted words omit quotes.
-     */
-    @Test(groups = { UNIT })
-    public void testDoubleQuotedWordsOmitQuotesOk() {
-        String[] result = split("\"hello\" \"world\"", false /* includeQuotes */);
-        assertArrayEquals(new String[] { "hello", "world" }, result);
-    }
-
-    /**
-     * Test escaped backslash in string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedBackslashInStringOk() {
-        String[] result = split("hello\\\\ world");
-        assertArrayEquals(new String[] { "hello\\", "world" }, result);
-    }
-
-    /**
-     * Test escaped backslash string in double quotes.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedBackslashStringInDoubleQuotesOk() {
-        String[] result = split("\"hello\\\\ world\"");
-        assertArrayEquals(new String[] { "\"hello\\ world\"" }, result);
-    }
-
-    /**
-     * Test escaped double quoted in single quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedDoubleQuotedInSingleQuotedStringOk() {
-        String[] result = split("'\"hello world\"'");
-        assertArrayEquals(new String[] { "'\"hello world\"'" }, result);
-    }
-
-    /**
-     * Test escaped double quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedDoubleQuotedStringOk() {
-        String[] result = split("\\\"hello world\\\"");
-        assertArrayEquals(new String[] { "\"hello", "world\"" }, result);
-    }
-
-    /**
-     * Test escaped key value pair.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedKeyValuePairOk() {
-        String[] result = split("key=\\'qux qoo\\'");
-        assertArrayEquals(new String[] { "key='qux", "qoo'" }, result);
-    }
-
-    /**
-     * Test escaped single quoted in double quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedSingleQuotedInDoubleQuotedStringOk() {
-        String[] result = split("\"\\'hello world\\'\"");
-        assertArrayEquals(new String[] { "\"'hello world'\"" }, result);
-    }
-
-    /**
-     * Test escaped single quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedSingleQuotedStringOk() {
-        String[] result = split("\\'hello world\\'");
-        assertArrayEquals(new String[] { "\'hello", "world\'" }, result);
-    }
-
-    /**
-     * Test escaped space string in double quotes.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedSpaceStringInDoubleQuotesOk() {
-        String[] result = split("\"hello\\ world\"");
-        assertArrayEquals(new String[] { "\"hello world\"" }, result);
-    }
-
-    /**
-     * Test escaped space string.
-     */
-    @Test(groups = { UNIT })
-    public void testEscapedSpaceStringOk() {
-        String[] result = split("hello\\ world");
-        assertArrayEquals(new String[] { "hello world" }, result);
-    }
-
-    /**
-     * Test key value pair in double quotes.
-     */
-    @Test(groups = { UNIT })
-    public void testKeyValuePairInDoubleQuotesOk() {
-        String[] result = split("\"key=\\\"qux qoo\\\"\"");
-        assertArrayEquals(new String[] { "\"key=\"qux qoo\"\"" }, result);
-    }
-
-    /**
-     * Test key value pair.
-     */
-    @Test(groups = { UNIT })
-    public void testKeyValuePairOk() {
-        String[] result = split("key='qux qoo'");
-        assertArrayEquals(new String[] { "key='qux qoo'" }, result);
-    }
-
-    /**
-     * Test os gi import package value.
-     */
-    @Test(groups = { UNIT })
-    public void testOSGiImportPackageValueOk() {
-        String[] result = split("\"org.foo.bar;version=\"1\",org.qux.quu;version=\"2\"\"");
-        assertArrayEquals(new String[] { "\"org.foo.bar;version=\"1\",org.qux.quu;version=\"2\"\"" }, result);
-    }
-
-    /**
-     * Test single quoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testSingleQuotedStringOk() {
-        String[] result = split("'hello world'");
-        assertArrayEquals(new String[] { "'hello world'" }, result);
-    }
-
-    /**
-     * Test single quoted words.
-     */
-    @Test(groups = { UNIT })
-    public void testSingleQuotedWordsOk() {
-        String[] result = split("'hello' 'world'");
-        assertArrayEquals(new String[] { "'hello'", "'world'" }, result);
-    }
-
-    /**
-     * Test single quoted words omit quotes.
-     */
-    @Test(groups = { UNIT })
-    public void testSingleQuotedWordsOmitQuotesOk() {
-        String[] result = split("'hello' 'world'", false /* includeQuotes */);
-        assertArrayEquals(new String[] { "hello", "world" }, result);
-    }
-
-    /**
-     * Test split empty string.
-     */
-    @Test(groups = { UNIT })
-    public void testSplitEmptyStringOk() {
-        String[] result = split("");
-        assertArrayEquals(new String[0], result);
-    }
-
-    /**
-     * Test split null value.
-     */
-    @Test(groups = { UNIT })
-    public void testSplitNullValueOk() {
-        String[] result = split(null);
-        assertArrayEquals(new String[0], result);
-    }
-
-    /**
-     * Test split on tab.
-     */
-    @Test(groups = { UNIT })
-    public void testSplitOnTabOk() {
-        String[] result = split("hello\tworld");
-        assertArrayEquals(new String[] { "hello", "world" }, result);
-    }
-
-    /**
-     * Test split whitespaces only.
-     */
-    @Test(groups = { UNIT })
-    public void testSplitWhitespacesOnlyOk() {
-        String[] result = split(" \t  ");
-        assertArrayEquals(new String[0], result);
-    }
-
-    /**
-     * Test unquoted command line argument.
-     */
-    @Test(groups = { UNIT })
-    public void testUnquotedCommandLineArgumentOk() {
-        String[] result =
-            split("fwOption=org.osgi.framework.system.packages.extra=org.w3c.dom.tral,org.w3c.dom.html,org.w3c.dom.ranges,sun.reflect,org.osgi.service.deploymentadmin;version=\"1.0\",org.osgi.service.deploymentadmin.spi;version=\"1.0\",org.osgi.service.cm;version=\"1.3\",org.osgi.service.event;version=\"1.2\",org.osgi.service.log;version=\"1.3\",org.osgi.service.metatype;version=\"1.1\",org.apache.ace.log;version=\"0.8.0\"");
-        assertArrayEquals(
-            new String[] { "fwOption=org.osgi.framework.system.packages.extra=org.w3c.dom.tral,org.w3c.dom.html,org.w3c.dom.ranges,sun.reflect,org.osgi.service.deploymentadmin;version=\"1.0\",org.osgi.service.deploymentadmin.spi;version=\"1.0\",org.osgi.service.cm;version=\"1.3\",org.osgi.service.event;version=\"1.2\",org.osgi.service.log;version=\"1.3\",org.osgi.service.metatype;version=\"1.1\",org.apache.ace.log;version=\"0.8.0\"" },
-            result);
-    }
-
-    /**
-     * Test unquoted string.
-     */
-    @Test(groups = { UNIT })
-    public void testUnquotedStringOk() {
-        String[] result = split("hello world");
-        assertArrayEquals(new String[] { "hello", "world" }, result);
-    }
-
-    /**
-     * Assert array equals.
-     * 
-     * @param expected the expected
-     * @param actual the actual
-     */
-    private void assertArrayEquals(Object[] expected, Object[] actual) {
-        assertEquals(expected.length, actual.length);
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], actual[i]);
-        }
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/TestUtil.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/TestUtil.java
deleted file mode 100644
index 3db79a4..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/TestUtil.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.impl;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-/**
- * Provides some convenience methods commonly used in the unit tests of ace-launcher.
- */
-public final class TestUtil {
-
-    /**
-     * Creates a new {@link TestUtil} instance, not used.
-     */
-    private TestUtil() {
-        // No-op
-    }
-
-    /**
-     * Returns the name of the running operating system.
-     * 
-     * @return the OS-name, in lower case.
-     */
-    public static String getOSName() {
-        return System.getProperty("os.name", "").toLowerCase();
-    }
-
-    /**
-     * Obtains the file denoted by the given path as resource, and treats it as properties file.
-     * 
-     * @param path the path to the resource to load, cannot be <code>null</code>.
-     * @return a properties file, never <code>null</code>.
-     * @throws IOException in case of I/O problems reading the properties file;
-     * @throws RuntimeException in case the given path is not a valid resource file.
-     */
-    public static Properties getProperties(String path) throws IOException {
-        InputStream is = TestUtil.class.getResourceAsStream(path);
-        if (is == null) {
-            throw new RuntimeException("File not found: " + path);
-        }
-        try {
-            Properties props = new Properties();
-            props.load(is);
-            return props;
-        }
-        finally {
-            is.close();
-        }
-    }
-
-    /**
-     * Sleeps for a given amount of milliseconds.
-     * 
-     * @param delayInMillis the delay to sleep, in milliseconds.
-     */
-    public static void sleep(int delayInMillis) {
-        try {
-            Thread.sleep(delayInMillis);
-        }
-        catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    /**
-     * Reads an entire file denoted by the given argument and returns its content as string.
-     * 
-     * @param file the file to read, cannot be <code>null</code>.
-     * @return the file contents, never <code>null</code>.
-     * @throws IOException in case of I/O problems reading the file.
-     */
-    public static String slurpFile(File file) throws IOException {
-        StringBuilder sb = new StringBuilder();
-        FileReader fr = new FileReader(file);
-        int ch;
-        try {
-            while ((ch = fr.read()) >= 0) {
-                sb.append((char) ch);
-            }
-        }
-        finally {
-            fr.close();
-        }
-        return sb.toString();
-    }
-    
-    /**
-     * Creates a unique temporary directory.
-     * 
-     * @return the unique temporary directory
-     */
-    public static File createTempDir() throws IOException {
-
-        File baseDir = new File(System.getProperty("java.io.tmpdir"));
-        String baseName = System.currentTimeMillis() + "-";
-
-        for (int counter = 0; counter < 1000; counter++) {
-            File tempDir = new File(baseDir, baseName + counter);
-            if (tempDir.mkdir()) {
-                return tempDir;
-            }
-        }
-        throw new IOException("Failed to create tmp directory");
-    }
-}
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/launch.properties b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/launch.properties
deleted file mode 100644
index fe21626..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/impl/launch.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-instance.count = 2
-executable.name = /bin/sh
-executable.args = -c 'sleep 1 && exit' -c 'echo "foo bar!\n"'
-executable.executable.processStreamListener = (foo=bar)
-executable.workingDir = /tmp
-executable.respawnAutomatically = false
-
-# Licensed to the Apache Software Foundation (ASF) under the terms of ASLv2 (http://www.apache.org/licenses/LICENSE-2.0).
\ No newline at end of file
diff --git a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/util/InputStreamRedirectorTest.java b/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/util/InputStreamRedirectorTest.java
deleted file mode 100644
index 412f1a6..0000000
--- a/org.apache.ace.processlauncher/test/org/apache/ace/processlauncher/test/util/InputStreamRedirectorTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ace.processlauncher.test.util;
-
-import static org.apache.ace.processlauncher.test.impl.TestUtil.sleep;
-import static org.apache.ace.test.utils.TestUtils.UNIT;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.ace.processlauncher.util.InputStreamRedirector;
-import org.mockito.Mockito;
-import org.testng.annotations.Test;
-
-/**
- * Test cases for {@link InputStreamRedirector}.
- */
-public class InputStreamRedirectorTest {
-
-    /**
-     * Tests that when an EOF is read on the input stream, the output stream is closed as well.
-     * 
-     * @throws IOException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testInputStreamEOFCausesOutputStreamToBeClosedOk() throws IOException {
-        InputStream myIS = new ByteArrayInputStream("hello world!".getBytes());
-        OutputStream mockOS = mock(OutputStream.class);
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS, mockOS);
-        redirector.run();
-
-        verify(mockOS).close();
-    }
-
-    /**
-     * Tests that the input stream is 1:1 copied to the given output stream.
-     * 
-     * @throws IOException not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testInputStreamIsVerbatimelyCopiedToOutputStreamOk() throws IOException {
-        String input = "hello world!";
-
-        InputStream myIS = new ByteArrayInputStream(input.getBytes());
-        ByteArrayOutputStream myOS = new ByteArrayOutputStream();
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS, myOS);
-        redirector.run();
-
-        assertEquals(input, myOS.toString());
-    }
-
-    /**
-     * Tests that we can interrupt a redirector and that it ceases its work.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testInterruptRedirectorOk() throws Exception {
-        InputStream myIS = createBlockingInputStream();
-        OutputStream myOS = mock(OutputStream.class);
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS, myOS);
-
-        Thread redirectorThread = new Thread(redirector);
-        redirectorThread.start();
-
-        // Sleep for a little while to ensure everything is up and running...
-        sleep(100);
-
-        redirectorThread.interrupt();
-
-        // Wait until the thread is really finished...
-        redirectorThread.join(1000);
-
-        verify(myIS, atLeast(1)).read(Mockito.<byte[]>any(), anyInt(), anyInt());
-        verify(myOS).close();
-    }
-
-    /**
-     * Tests that we can recover when the input stream throws an I/O exception.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testRecoverFromExceptionInInputStreamWithoutOutputStreamOk() throws Exception {
-        InputStream myIS = createExceptionThrowingInputStream();
-        ByteArrayOutputStream myOS = new ByteArrayOutputStream();
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS, myOS);
-
-        redirector.run();
-
-        verify(myIS, atLeast(1)).read(Mockito.<byte[]>any(), anyInt(), anyInt());
-
-        // Verify that the exception is indeed logged...
-        String stdout = myOS.toString();
-
-        assertTrue(stdout.contains("IGNORE ME! TEST EXCEPTION!"));
-    }
-
-    /**
-     * Tests that we can recover when the input stream throws an I/O exception.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testRecoverFromExceptionInInputStreamWithOutputStreamOk() throws Exception {
-        InputStream myIS = createExceptionThrowingInputStream();
-        OutputStream myOS = mock(OutputStream.class);
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS, myOS);
-
-        redirector.run();
-
-        verify(myIS, atLeast(1)).read(Mockito.<byte[]>any(), anyInt(), anyInt());
-        verify(myOS).close();
-    }
-
-    /**
-     * Tests that we can recover when the input stream throws an I/O exception.
-     * 
-     * @throws Exception not part of this test case.
-     */
-    @Test(groups = { UNIT })
-    public void testWithoutOutputStreamOk() throws Exception {
-        InputStream myIS = new ByteArrayInputStream("hello world!".getBytes());
-
-        InputStreamRedirector redirector = new InputStreamRedirector(myIS);
-
-        redirector.run();
-    }
-
-    /**
-     * Creates an input stream that keeps pretending its returning data when its
-     * {@link InputStream#read(byte[])} method is called.
-     * 
-     * @return a mocked {@link InputStream} instance, never <code>null</code>.
-     */
-    private InputStream createBlockingInputStream() throws IOException {
-        InputStream is = mock(InputStream.class);
-        when(is.read(Mockito.<byte[]>any(), anyInt(), anyInt())).thenReturn(Integer.valueOf(10));
-        return is;
-    }
-
-    /**
-     * Creates an input stream that keeps pretending its returning data when its
-     * {@link InputStream#read(byte[])} method is called.
-     * 
-     * @return a mocked {@link InputStream} instance, never <code>null</code>.
-     */
-    private InputStream createExceptionThrowingInputStream() throws IOException {
-        InputStream is = mock(InputStream.class);
-        when(is.read(Mockito.<byte[]>any(), anyInt(), anyInt())).thenThrow(
-            new IOException("IGNORE ME! TEST EXCEPTION!"));
-        return is;
-    }
-}