diff --git a/gogo/launcher/NOTICE b/gogo/launcher/NOTICE
deleted file mode 100644
index f854a8b..0000000
--- a/gogo/launcher/NOTICE
+++ /dev/null
@@ -1,21 +0,0 @@
-Apache Felix Gogo Launcher
-Copyright 2009 The Apache Software Foundation
-
-
-I. Included Software
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-
-II. Used Software
-
-This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
-Licensed under the Apache License 2.0.
-
-
-III. License Summary
-- Apache License 2.0
diff --git a/gogo/launcher/pom.xml b/gogo/launcher/pom.xml
deleted file mode 100644
index ba9d684..0000000
--- a/gogo/launcher/pom.xml
+++ /dev/null
@@ -1,100 +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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <parent>
-        <groupId>org.apache.felix.gogo</groupId>
-        <artifactId>gogo</artifactId>
-        <version>0.5.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-    <packaging>bundle</packaging>
-    <name>Apache Felix Gogo Shell Launcher</name>
-    <artifactId>org.apache.felix.gogo.launcher</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.framework</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix.gogo</groupId>
-            <artifactId>org.apache.felix.gogo.console</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                        <Export-Package>
-                            org.osgi.service.command; version=${project.version},
-                            org.osgi.service.threadio; version=${project.version},
-                            org.apache.felix.gogo.commands; version=${project.version}
-                        </Export-Package>
-                        <Import-Package>
-                            org.osgi.service.component*; resolution:=optional,
-                            org.osgi.service.log*; resolution:=optional,
-                            org.osgi.service.packageadmin*; resolution:=optional,
-                            org.osgi.service.startlevel*; resolution:=optional,
-                            *
-                        </Import-Package>
-                        <Private-Package>org.apache.felix.gogo.*</Private-Package>
-                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
-                        <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
-                        <Bundle-Activator>org.apache.felix.gogo.runtime.Activator</Bundle-Activator>
-                        <Include-Resource>{maven-resources},META-INF/NOTICE=NOTICE</Include-Resource>
-                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
-                        <_removeheaders>Private-Package,Ignore-Package,Include-Resource</_removeheaders>
-                    </instructions>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>rat-maven-plugin</artifactId>
-                <configuration>
-                    <excludeSubProjects>false</excludeSubProjects>
-                    <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
-                    <useMavenDefaultExcludes>true</useMavenDefaultExcludes>
-                    <excludes>
-                        <param>doc/*</param>
-                        <param>maven-eclipse.xml</param>
-                        <param>.checkstyle</param>
-                        <param>.externalToolBuilders/*</param>
-                    </excludes>
-                </configuration>
-            </plugin>
-            <plugin>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/gogo/launcher/src/main/java/org/apache/felix/gogo/launcher/Launcher.java b/gogo/launcher/src/main/java/org/apache/felix/gogo/launcher/Launcher.java
deleted file mode 100644
index 123e0b9..0000000
--- a/gogo/launcher/src/main/java/org/apache/felix/gogo/launcher/Launcher.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.gogo.launcher;
-
-import org.apache.felix.gogo.runtime.shell.CommandProcessorImpl;
-import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
-import org.apache.felix.gogo.console.stdio.Console;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.launch.FrameworkFactory;
-import org.osgi.framework.launch.Framework;
-import org.osgi.service.command.CommandSession;
-
-import java.io.*;
-import java.lang.reflect.Constructor;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.*;
-
-
-public class Launcher
-{
-    static List<URL> classpath = new ArrayList<URL>();
-    static File cwd = new File("").getAbsoluteFile();
-
-    public static void main(String args[]) throws Exception
-    {
-        StringBuffer sb = new StringBuffer();
-        String fwkClassName = null;
-        PrintStream out = System.out;
-        InputStream in = System.in;
-        boolean console = false;
-
-        for (int i = 0; i < args.length; i++)
-        {
-            String arg = args[i];
-            if (arg.equals("-f"))
-            {
-                fwkClassName = args[++i];
-            }
-            else
-            {
-                if (arg.equals("-cp") || arg.equals("-classpath"))
-                {
-                    classpath(args[++i]);
-                }
-                else
-                {
-                    if (arg.equals("-console"))
-                    {
-                        console = true;
-                    }
-                    else
-                    {
-                        if (arg.equals("-i"))
-                        {
-                            in = new FileInputStream(args[++i]);
-                        }
-                        else
-                        {
-                            if (arg.equals("-o"))
-                            {
-                                out = new PrintStream(new FileOutputStream(args[++i]));
-                            }
-                            else
-                            {
-                                sb.append(' ');
-                                sb.append(arg);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        URL[] urls = classpath.toArray(new URL[classpath.size()]);
-        URLClassLoader cl = new URLClassLoader(urls, Launcher.class.getClassLoader());
-
-        Properties p = new Properties(System.getProperties());
-
-        Framework framework;
-        if (fwkClassName == null)
-        {
-            framework = getFrameworkFactory(cl).newFramework(p);
-        }
-        else
-        {
-            Class<?> fw = cl.loadClass(fwkClassName);
-            Constructor<?> c = fw.getConstructor(Map.class, List.class);
-            framework = (Framework) c.newInstance(p);
-        }
-
-        ThreadIOImpl threadio = new ThreadIOImpl();
-        threadio.start();
-
-        CommandProcessorImpl shell = new CommandProcessorImpl(threadio);
-
-        CommandSession session = shell.createSession(in, out, System.err);
-        session.put("shell", shell);
-        session.put("threadio", threadio);
-
-        session.execute(sb);
-        out.flush();
-
-        if (framework.getState() == Bundle.ACTIVE)
-        {
-        }
-        if (console)
-        {
-            Console cons = new Console();
-            cons.setSession(session);
-            cons.run();
-        }
-    }
-
-    /**
-     * Simple method to search for META-INF/services for a FrameworkFactory
-     * provider. It simply looks for the first non-commented line and assumes
-     * it is the name of the provider class.
-     * @return a <tt>FrameworkFactory</tt> instance.
-     * @throws Exception if anything goes wrong.
-    **/
-    private static FrameworkFactory getFrameworkFactory(ClassLoader cl)
-        throws Exception
-    {
-        URL url = cl.getResource(
-            "META-INF/services/org.osgi.framework.launch.FrameworkFactory");
-        if (url != null)
-        {
-            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
-            try
-            {
-                for (String s = br.readLine(); s != null; s = br.readLine())
-                {
-                    s = s.trim();
-                    // Try to load first non-empty, non-commented line.
-                    if ((s.length() > 0) && (s.charAt(0) != '#'))
-                    {
-                        return (FrameworkFactory) cl.loadClass(s).newInstance();
-                    }
-                }
-            }
-            finally
-            {
-                if (br != null) br.close();
-            }
-        }
-
-        throw new Exception("Could not find framework factory.");
-    }
-
-    private static void classpath(String string) throws MalformedURLException
-    {
-        StringTokenizer st = new StringTokenizer(string, File.pathSeparator);
-        while (st.hasMoreTokens())
-        {
-            String part = st.nextToken();
-            if (part.equals("."))
-            {
-                classpath.add(cwd.toURL());
-            }
-
-            File f = new File(part);
-            if (!f.isAbsolute())
-            {
-                f = new File(cwd, part);
-            }
-            if (f.exists())
-            {
-                classpath.add(f.toURL());
-            }
-            else
-            {
-                System.err.println("Can not find " + part);
-            }
-        }
-    }
-}
