diff --git a/gogo/console/pom.xml b/gogo/console/pom.xml
index 8c430a7..5c2e4be 100644
--- a/gogo/console/pom.xml
+++ b/gogo/console/pom.xml
@@ -24,8 +24,8 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>bundle</packaging>
-    <name>Apache Felix Gogo Shell Console</name>
-    <artifactId>org.apache.felix.gogo.console</artifactId>
+    <name>Apache Felix Gogo Shell</name>
+    <artifactId>org.apache.felix.gogo.shell</artifactId>
     <version>0.5.0-SNAPSHOT</version>
     <dependencies>
         <dependency>
@@ -54,16 +54,15 @@
                         <Export-Package>
                         </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>
+                        <Private-Package>
+			    org.apache.felix.gogo.shell,
+			    org.apache.felix.gogo.options
+			</Private-Package>
                         <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
                         <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
-                        <Bundle-Activator>org.apache.felix.gogo.console.Activator</Bundle-Activator>
+                        <Bundle-Activator>org.apache.felix.gogo.shell.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>
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/console/Activator.java b/gogo/console/src/main/java/org/apache/felix/gogo/console/Activator.java
deleted file mode 100644
index dc865cc..0000000
--- a/gogo/console/src/main/java/org/apache/felix/gogo/console/Activator.java
+++ /dev/null
@@ -1,72 +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.console;
-
-import org.apache.felix.gogo.console.stdio.StdioConsole;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.command.CommandProcessor;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class Activator implements BundleActivator
-{
-
-    private ServiceTracker commandProcessorTracker;
-    private StdioConsole console;
-
-    public void start(final BundleContext context) throws Exception
-    {
-        commandProcessorTracker = new ServiceTracker(context, CommandProcessor.class.getName(), null) {
-            @Override
-            public Object addingService(ServiceReference reference)
-            {
-                CommandProcessor processor = (CommandProcessor) super.addingService(reference);
-                startConsole(processor);
-                return processor;
-            }
-
-            @Override
-            public void removedService(ServiceReference reference, Object service)
-            {
-                if (console != null) {
-                    console.close();
-                    console = null;
-                }
-                super.removedService(reference, service);
-            }
-        };
-        commandProcessorTracker.open();
-    }
-
-    protected void startConsole(final CommandProcessor processor) {
-        console = new StdioConsole();
-        console.setProcessor(processor);
-        console.start();
-    }
-
-    public void stop(BundleContext context) throws Exception
-    {
-        if (console != null) {
-            console.close();
-        }
-        commandProcessorTracker.close();
-    }
-
-}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/Console.java b/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/Console.java
deleted file mode 100644
index 7756a74..0000000
--- a/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/Console.java
+++ /dev/null
@@ -1,186 +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.console.stdio;
-
-import org.osgi.service.command.CommandSession;
-import org.osgi.service.command.Converter;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Console implements Runnable
-{
-    StringBuilder sb;
-    CommandSession session;
-    List<CharSequence> history = new ArrayList<CharSequence>();
-    int current = 0;
-    boolean quit;
-
-    public void setSession(CommandSession session)
-    {
-        this.session = session;
-    }
-
-    public void run()
-    {
-        try
-        {
-            while (!quit)
-            {
-                try
-                {
-                    CharSequence line = getLine(session.getKeyboard());
-                    if (line != null)
-                    {
-                        history.add(line);
-                        if (history.size() > 40)
-                        {
-                            history.remove(0);
-                        }
-                        Object result = session.execute(line);
-                        if (result != null)
-                        {
-                            session.getConsole().println(session.format(result, Converter.INSPECT));
-                        }
-                    }
-                    else
-                    {
-                        quit = true;
-                    }
-
-                }
-                catch (InvocationTargetException ite)
-                {
-                    session.getConsole().println("E: " + ite.getTargetException());
-                    session.put("exception", ite.getTargetException());
-                }
-                catch (Throwable e)
-                {
-                    if (!quit)
-                    {
-                        session.getConsole().println("E: " + e.getMessage());
-                        session.put("exception", e);
-                    }
-                }
-            }
-        }
-        catch (Exception e)
-        {
-            if (!quit)
-            {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    CharSequence getLine(InputStream in) throws IOException
-    {
-        sb = new StringBuilder();
-        session.getConsole().print("$ ");
-        int outer = 0;
-        while (!quit)
-        {
-            session.getConsole().flush();
-            int c = in.read();
-            if (c < 0)
-            {
-                quit = true;
-            }
-            else
-            {
-                switch (c)
-                {
-                    case '\r':
-                        break;
-                    case '\n':
-                        if (outer == 0 && sb.length() > 0)
-                        {
-                            return sb;
-                        }
-                        else
-                        {
-                            session.getConsole().print("$ ");
-                        }
-                        break;
-
-                    case '\u001b':
-                        c = in.read();
-                        if (c == '[')
-                        {
-                            c = in.read();
-                            session.getConsole().print("\b\b\b");
-                            switch (c)
-                            {
-                                case 'A':
-                                    history(current - 1);
-                                    break;
-                                case 'B':
-                                    history(current + 1);
-                                    break;
-                                case 'C': // right(); break;
-                                case 'D': // left(); break;
-                            }
-                        }
-                        break;
-
-                    case '\b':
-                        if (sb.length() > 0)
-                        {
-                            session.getConsole().print("\b \b");
-                            sb.deleteCharAt(sb.length() - 1);
-                        }
-                        break;
-
-                    default:
-                        sb.append((char) c);
-                        break;
-                }
-            }
-        }
-        return null;
-    }
-
-    void history(int n)
-    {
-        if (n < 0 || n > history.size())
-        {
-            return;
-        }
-        current = n;
-        for (int i = 0; i < sb.length(); i++)
-        {
-            session.getConsole().print("\b \b");
-        }
-
-        sb = new StringBuilder(history.get(current));
-        session.getConsole().print(sb);
-    }
-
-    public void close()
-    {
-        quit = true;
-    }
-
-    public void open()
-    {
-    }
-}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/StdioConsole.java b/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/StdioConsole.java
deleted file mode 100644
index e83c1b4..0000000
--- a/gogo/console/src/main/java/org/apache/felix/gogo/console/stdio/StdioConsole.java
+++ /dev/null
@@ -1,47 +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.console.stdio;
-
-import org.osgi.service.command.CommandProcessor;
-
-public class StdioConsole extends Thread
-{
-    final Console console = new Console();
-
-    public StdioConsole()
-    {
-        super("StdioConsole");
-    }
-
-    public void close()
-    {
-        console.close();
-        interrupt();
-    }
-
-    public void setProcessor(CommandProcessor processor)
-    {
-        console.setSession(processor.createSession(System.in, System.out, System.err));
-    }
-
-    public void run()
-    {
-        console.run();
-    }
-}
\ No newline at end of file
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/Handler.java b/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/Handler.java
deleted file mode 100644
index 4b12381..0000000
--- a/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/Handler.java
+++ /dev/null
@@ -1,69 +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.console.telnet;
-
-import org.apache.felix.gogo.console.stdio.Console;
-import org.osgi.service.command.CommandSession;
-
-import java.io.IOException;
-import java.net.Socket;
-
-public class Handler extends Thread
-{
-    TelnetShell master;
-    Socket socket;
-    CommandSession session;
-    Console console;
-
-    public Handler(TelnetShell master, CommandSession session, Socket socket) throws IOException
-    {
-        this.master = master;
-        this.socket = socket;
-        this.session = session;
-    }
-
-    public void run()
-    {
-        try
-        {
-            console = new Console();
-            console.setSession(session);
-            console.run();
-        }
-        finally
-        {
-            close();
-            master.handlers.remove(this);
-        }
-    }
-
-    public void close()
-    {
-        session.close();
-        try
-        {
-            socket.close();
-        }
-        catch (IOException e)
-        {
-            // Ignore, this is close
-        }
-    }
-
-}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/TelnetShell.java b/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/TelnetShell.java
deleted file mode 100644
index 4b02d74..0000000
--- a/gogo/console/src/main/java/org/apache/felix/gogo/console/telnet/TelnetShell.java
+++ /dev/null
@@ -1,145 +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.console.telnet;
-
-import org.osgi.service.command.CommandProcessor;
-import org.osgi.service.command.CommandSession;
-import org.osgi.service.component.ComponentContext;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.BindException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-
-public class TelnetShell extends Thread
-{
-    boolean quit;
-    CommandProcessor processor;
-    ServerSocket server;
-    int port = 2019;
-    List<Handler> handlers = new ArrayList<Handler>();
-
-    protected void activate(ComponentContext context)
-    {
-        String s = (String) context.getProperties().get("port");
-        if (s != null)
-        {
-            port = Integer.parseInt(s);
-        }
-        System.out.println("Telnet Listener at port " + port);
-        start();
-    }
-
-    protected void deactivate(ComponentContext ctx) throws Exception
-    {
-        try
-        {
-            quit = true;
-            server.close();
-            interrupt();
-        }
-        catch (Exception e)
-        {
-            // Ignore
-        }
-    }
-
-    public void run()
-    {
-        int delay = 0;
-        try
-        {
-            while (!quit)
-            {
-                try
-                {
-                    server = new ServerSocket(port);
-                    delay = 5;
-                    while (!quit)
-                    {
-                        Socket socket = server.accept();
-                        CommandSession session = processor.createSession(socket.getInputStream(), new PrintStream(socket.getOutputStream()), System.err);
-                        Handler handler = new Handler(this, session, socket);
-                        handlers.add(handler);
-                        handler.start();
-                    }
-                }
-                catch (BindException be)
-                {
-                    delay += 5;
-                    System.err.println("Can not bind to port " + port);
-                    try
-                    {
-                        Thread.sleep(delay * 1000);
-                    }
-                    catch (InterruptedException e)
-                    {
-                        // who cares?
-                    }
-                }
-                catch (Exception e)
-                {
-                    if (!quit)
-                    {
-                        e.printStackTrace();
-                    }
-                }
-                finally
-                {
-                    try
-                    {
-                        server.close();
-                        Thread.sleep(2000);
-                    }
-                    catch (Exception ie)
-                    {
-                        //
-                    }
-                }
-            }
-
-        }
-        finally
-        {
-            try
-            {
-                if (server != null)
-                {
-                    server.close();
-                }
-            }
-            catch (IOException e)
-            {
-                //
-            }
-            for (Handler handler : handlers)
-            {
-                handler.close();
-            }
-        }
-    }
-
-    public void setProcessor(CommandProcessor processor)
-    {
-        this.processor = processor;
-    }
-}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/options/Option.java b/gogo/console/src/main/java/org/apache/felix/gogo/options/Option.java
new file mode 100644
index 0000000..6b4a496
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/options/Option.java
@@ -0,0 +1,159 @@
+/*
+ * 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.options;
+
+import java.util.List;
+
+public interface Option {
+    /**
+     * stop parsing on the first unknown option. This allows one parser to get its own options and
+     * then pass the remaining options to another parser.
+     * 
+     * @param stopOnBadOption
+     */
+    Option setStopOnBadOption(boolean stopOnBadOption);
+
+    /**
+     * require options to precede args. Default is false, so options can appear between or after
+     * args.
+     * 
+     * @param optionsFirst
+     */
+    Option setOptionsFirst(boolean optionsFirst);
+
+    /**
+     * parse arguments. If skipArgv0 is true, then parsing begins at arg1. This allows for commands
+     * where argv0 is the command name rather than a real argument.
+     * 
+     * @param argv
+     * @param skipArg0
+     * @return
+     */
+    Option parse(List<? extends Object> argv, boolean skipArg0);
+
+    /**
+     * parse arguments.
+     * 
+     * @see {@link #parse(List, boolean)
+
+     */
+    Option parse(List<? extends Object> argv);
+
+    /**
+     * parse arguments.
+     * 
+     * @see {@link #parse(List, boolean)
+
+     */
+    Option parse(Object[] argv, boolean skipArg0);
+
+    /**
+     * parse arguments.
+     * 
+     * @see {@link #parse(List, boolean)
+
+     */
+    Option parse(Object[] argv);
+
+    /**
+     * test whether specified option has been explicitly set.
+     * 
+     * @param name
+     * @return
+     */
+    boolean isSet(String name);
+
+    /**
+     * get value of named option. If multiple options given, this method returns the last one. Use
+     * {@link #getList(String)} to get all values.
+     * 
+     * @param name
+     * @return
+     * @throws IllegalArgumentException
+     *             if value is not a String.
+     */
+    String get(String name);
+
+    /**
+     * get list of all values for named option.
+     * 
+     * @param name
+     * @return empty list if option not given and no default specified.
+     * @throws IllegalArgumentException
+     *             if all values are not Strings.
+     */
+    List<String> getList(String name);
+
+    /**
+     * get value of named option as an Object. If multiple options given, this method returns the
+     * last one. Use {@link #getObjectList(String)} to get all values.
+     * 
+     * @param name
+     * @return
+     */
+    Object getObject(String name);
+
+    /**
+     * get list of all Object values for named option.
+     * 
+     * @param name
+     * @return
+     */
+    List<Object> getObjectList(String name);
+
+    /**
+     * get value of named option as a Number.
+     * 
+     * @param name
+     * @return
+     * @throws IllegalArgumentException
+     *             if argument is not a Number.
+     */
+    int getNumber(String name);
+
+    /**
+     * get remaining non-options args as Strings.
+     * 
+     * @return
+     * @throws IllegalArgumentException
+     *             if args are not Strings.
+     */
+    List<String> args();
+
+    /**
+     * get remaining non-options args as Objects.
+     * 
+     * @return
+     */
+    List<Object> argObjects();
+
+    /**
+     * print usage message to System.err.
+     */
+    void usage();
+
+    /**
+     * print specified usage error to System.err. You should explicitly throw the returned
+     * exception.
+     * 
+     * @param error
+     * @return IllegalArgumentException
+     */
+    IllegalArgumentException usageError(String error);
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/options/Options.java b/gogo/console/src/main/java/org/apache/felix/gogo/options/Options.java
new file mode 100644
index 0000000..e2fdba0
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/options/Options.java
@@ -0,0 +1,528 @@
+/*
+ * 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.options;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Yet another GNU long options parser. This one is configured by parsing its Usage string.
+ */
+public class Options implements Option {
+    public static void main(String[] args) {
+        final String[] usage = {
+            "test - test Options usage",
+            "  text before Usage: is displayed when usage() is called and no error has occurred.",
+            "  so can be used as a simple help message.",
+            "",
+            "Usage: testOptions [OPTION]... PATTERN [FILES]...",
+            "  Output control: arbitary non-option text can be included.",
+            "  -? --help                show help",
+            "  -c --count=COUNT           show COUNT lines",
+            "  -h --no-filename         suppress the prefixing filename on output",
+            "  -q --quiet, --silent     suppress all normal output",
+            "     --binary-files=TYPE   assume that binary files are TYPE",
+            "                           TYPE is 'binary', 'text', or 'without-match'",
+            "  -I                       equivalent to --binary-files=without-match",
+            "  -d --directories=ACTION  how to handle directories (default=skip)",
+            "                           ACTION is 'read', 'recurse', or 'skip'",
+            "  -D --devices=ACTION      how to handle devices, FIFOs and sockets",
+            "                           ACTION is 'read' or 'skip'",
+            "  -R, -r --recursive       equivalent to --directories=recurse" };
+
+        Option opt = Options.compile(usage).parse(args);
+
+        if (opt.isSet("help")) {
+            opt.usage(); // includes text before Usage:
+            return;
+        }
+
+        if (opt.args().size() == 0)
+            throw opt.usageError("PATTERN not specified");
+
+        System.out.println(opt);
+        if (opt.isSet("count"))
+            System.out.println("count = " + opt.getNumber("count"));
+        System.out.println("--directories specified: " + opt.isSet("directories"));
+        System.out.println("directories=" + opt.get("directories"));
+    }
+
+    public static final String NL = System.getProperty("line.separator", "\n");
+
+    // Note: need to double \ within ""
+    private static final String regex = "(?x)\\s*" + "(?:-([^-]))?" + // 1: short-opt-1
+            "(?:,?\\s*-(\\w))?" + // 2: short-opt-2
+            "(?:,?\\s*--(\\w[\\w-]*)(=\\w+)?)?" + // 3: long-opt-1 and 4:arg-1
+            "(?:,?\\s*--(\\w[\\w-]*))?" + // 5: long-opt-2
+            ".*?(?:\\(default=(.*)\\))?\\s*"; // 6: default
+
+    private static final int GROUP_SHORT_OPT_1 = 1;
+    private static final int GROUP_SHORT_OPT_2 = 2;
+    private static final int GROUP_LONG_OPT_1 = 3;
+    private static final int GROUP_ARG_1 = 4;
+    private static final int GROUP_LONG_OPT_2 = 5;
+    private static final int GROUP_DEFAULT = 6;
+
+    private final Pattern parser = Pattern.compile(regex);
+    private final Pattern uname = Pattern.compile("^Usage:\\s+(\\w+)");
+
+    private final Map<String, Boolean> unmodifiableOptSet;
+    private final Map<String, Object> unmodifiableOptArg;
+    private final Map<String, Boolean> optSet = new HashMap<String, Boolean>();
+    private final Map<String, Object> optArg = new HashMap<String, Object>();
+
+    private final Map<String, String> optName = new HashMap<String, String>();
+    private final Map<String, String> optAlias = new HashMap<String, String>();
+    private final List<Object> xargs = new ArrayList<Object>();
+    private List<String> args = null;
+
+    private static final String UNKNOWN = "unknown";
+    private String usageName = UNKNOWN;
+    private int usageIndex = 0;
+
+    private final String[] spec;
+    private final String[] gspec;
+    private final String defOpts;
+    private final String[] defArgs;
+    private PrintStream errStream = System.err;
+    private String error = null;
+
+    private boolean optionsFirst = false;
+    private boolean stopOnBadOption = false;
+
+    public static Option compile(String[] optSpec) {
+        return new Options(optSpec, null, null);
+    }
+
+    public static Option compile(String optSpec) {
+        return compile(optSpec.split("\\n"));
+    }
+
+    public static Option compile(String[] optSpec, Option gopt) {
+        return new Options(optSpec, null, gopt);
+    }
+
+    public static Option compile(String[] optSpec, String[] gspec) {
+        return new Options(optSpec, gspec, null);
+    }
+
+    public Option setStopOnBadOption(boolean stopOnBadOption) {
+        this.stopOnBadOption = stopOnBadOption;
+        return this;
+    }
+
+    public Option setOptionsFirst(boolean optionsFirst) {
+        this.optionsFirst = optionsFirst;
+        return this;
+    }
+
+    public boolean isSet(String name) {
+        if (!optSet.containsKey(name))
+            throw new IllegalArgumentException("option not defined in spec: " + name);
+
+        return optSet.get(name);
+    }
+
+    public Object getObject(String name) {
+        if (!optArg.containsKey(name))
+            throw new IllegalArgumentException("option not defined with argument: " + name);
+
+        List<Object> list = getObjectList(name);
+
+        return list.isEmpty() ? "" : list.get(list.size() - 1);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<Object> getObjectList(String name) {
+        List<Object> list;
+        Object arg = optArg.get(name);
+
+        if ( arg == null ) {
+            throw new IllegalArgumentException("option not defined with argument: " + name);
+        }
+        
+        if (arg instanceof String) { // default value
+            list = new ArrayList<Object>();
+            if (!"".equals(arg))
+                list.add(arg);
+        }
+        else {
+            list = (List<Object>) arg;
+        }
+
+        return list;
+    }
+
+    public List<String> getList(String name) {
+        ArrayList<String> list = new ArrayList<String>();
+        for (Object o : getObjectList(name)) {
+            try {
+                list.add((String) o);
+            } catch (ClassCastException e) {
+                throw new IllegalArgumentException("option not String: " + name);
+            }
+        }
+        return list;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void addArg(String name, Object value) {
+        List<Object> list;
+        Object arg = optArg.get(name);
+
+        if (arg instanceof String) { // default value
+            list = new ArrayList<Object>();
+            optArg.put(name, list);
+        }
+        else {
+            list = (List<Object>) arg;
+        }
+
+        list.add(value);
+    }
+
+    public String get(String name) {
+        try {
+            return (String) getObject(name);
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("option not String: " + name);
+        }
+    }
+
+    public int getNumber(String name) {
+        String number = get(name);
+        try {
+            if (number != null)
+                return Integer.parseInt(number);
+            return 0;
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("option '" + name + "' not Number: " + number);
+        }
+    }
+
+    public List<Object> argObjects() {
+        return xargs;
+    }
+
+    public List<String> args() {
+        if (args == null) {
+            args = new ArrayList<String>();
+            for (Object arg : xargs) {
+                args.add(arg == null ? "null" : arg.toString());
+            }
+        }
+        return args;
+    }
+
+    public void usage() {
+        StringBuilder buf = new StringBuilder();
+        int index = 0;
+
+        if (error != null) {
+            buf.append(error);
+            buf.append(NL);
+            index = usageIndex;
+        }
+
+        for (int i = index; i < spec.length; ++i) {
+            buf.append(spec[i]);
+            buf.append(NL);
+        }
+
+        String msg = buf.toString();
+
+        if (errStream != null) {
+            errStream.print(msg);
+        }
+    }
+
+    /**
+     * prints usage message and returns IllegalArgumentException, for you to throw.
+     */
+    public IllegalArgumentException usageError(String s) {
+        error = usageName + ": " + s;
+        usage();
+        return new IllegalArgumentException(error);
+    }
+
+    // internal constructor
+    private Options(String[] spec, String[] gspec, Option opt) {
+        this.gspec = gspec;
+        Options gopt = (Options) opt;
+
+        if (gspec == null && gopt == null) {
+            this.spec = spec;
+        }
+        else {
+            ArrayList<String> list = new ArrayList<String>();
+            list.addAll(Arrays.asList(spec));
+            list.addAll(Arrays.asList(gspec != null ? gspec : gopt.gspec));
+            this.spec = list.toArray(new String[0]);
+        }
+
+        Map<String, Boolean> myOptSet = new HashMap<String, Boolean>();
+        Map<String, Object> myOptArg = new HashMap<String, Object>();
+
+        parseSpec(myOptSet, myOptArg);
+
+        if (gopt != null) {
+            for (Entry<String, Boolean> e : gopt.optSet.entrySet()) {
+                if (e.getValue())
+                    myOptSet.put(e.getKey(), true);
+            }
+
+            for (Entry<String, Object> e : gopt.optArg.entrySet()) {
+                if (!e.getValue().equals(""))
+                    myOptArg.put(e.getKey(), e.getValue());
+            }
+
+            gopt.reset();
+        }
+
+        unmodifiableOptSet = Collections.unmodifiableMap(myOptSet);
+        unmodifiableOptArg = Collections.unmodifiableMap(myOptArg);
+
+        defOpts = System.getenv(usageName.toUpperCase() + "_OPTS");
+        defArgs = (defOpts != null) ? defOpts.split("\\s+") : new String[0];
+    }
+
+    /**
+     * parse option spec.
+     */
+    private void parseSpec(Map<String, Boolean> myOptSet, Map<String, Object> myOptArg) {
+        int index = 0;
+        for (String line : spec) {
+            Matcher m = parser.matcher(line);
+
+            if (m.matches()) {
+                final String opt = m.group(GROUP_LONG_OPT_1);
+                final String name = (opt != null) ? opt : m.group(GROUP_SHORT_OPT_1);
+
+                if (name != null) {
+                    if (myOptSet.containsKey(name))
+                        throw new IllegalArgumentException("duplicate option in spec: --" + name);
+                    myOptSet.put(name, false);
+                }
+
+                String dflt = (m.group(GROUP_DEFAULT) != null) ? m.group(GROUP_DEFAULT) : "";
+                if (m.group(GROUP_ARG_1) != null)
+                    myOptArg.put(opt, dflt);
+
+                String opt2 = m.group(GROUP_LONG_OPT_2);
+                if (opt2 != null) {
+                    optAlias.put(opt2, opt);
+                    myOptSet.put(opt2, false);
+                    if (m.group(GROUP_ARG_1) != null)
+                        myOptArg.put(opt2, "");
+                }
+
+                for (int i = 0; i < 2; ++i) {
+                    String sopt = m.group(i == 0 ? GROUP_SHORT_OPT_1 : GROUP_SHORT_OPT_2);
+                    if (sopt != null) {
+                        if (optName.containsKey(sopt))
+                            throw new IllegalArgumentException("duplicate option in spec: -" + sopt);
+                        optName.put(sopt, name);
+                    }
+                }
+            }
+
+            if (usageName == UNKNOWN) {
+                Matcher u = uname.matcher(line);
+                if (u.find()) {
+                    usageName = u.group(1);
+                    usageIndex = index;
+                }
+            }
+
+            index++;
+        }
+    }
+
+    private void reset() {
+        optSet.clear();
+        optSet.putAll(unmodifiableOptSet);
+        optArg.clear();
+        optArg.putAll(unmodifiableOptArg);
+        xargs.clear();
+        args = null;
+        error = null;
+    }
+
+    public Option parse(Object[] argv) {
+        return parse(argv, false);
+    }
+
+    public Option parse(List<? extends Object> argv) {
+        return parse(argv, false);
+    }
+
+    public Option parse(Object[] argv, boolean skipArg0) {
+        if (null == argv)
+            throw new IllegalArgumentException("argv is null");
+        
+        return parse(Arrays.asList(argv), skipArg0);
+    }
+
+    public Option parse(List<? extends Object> argv, boolean skipArg0) {
+        reset();
+        List<Object> args = new ArrayList<Object>();
+        args.addAll(Arrays.asList(defArgs));
+
+        for (Object arg : argv) {
+            if (skipArg0) {
+                skipArg0 = false;
+                usageName = arg.toString();
+            }
+            else {
+                args.add(arg);
+            }
+        }
+
+        String needArg = null;
+        String needOpt = null;
+        boolean endOpt = false;
+
+        for (Object oarg : args) {
+            String arg = oarg == null ? "null" : oarg.toString();
+
+            if (endOpt) {
+                xargs.add(oarg);
+            }
+            else if (needArg != null) {
+                addArg(needArg, oarg);
+                needArg = null;
+                needOpt = null;
+            }
+            else if (!arg.startsWith("-") || "-".equals(oarg)) {
+                if (optionsFirst)
+                    endOpt = true;
+                xargs.add(oarg);
+            }
+            else {
+                if (arg.equals("--"))
+                    endOpt = true;
+                else if (arg.startsWith("--")) {
+                    int eq = arg.indexOf("=");
+                    String value = (eq == -1) ? null : arg.substring(eq + 1);
+                    String name = arg.substring(2, ((eq == -1) ? arg.length() : eq));
+                    List<String> names = new ArrayList<String>();
+
+                    if (optSet.containsKey(name)) {
+                        names.add(name);
+                    }
+                    else {
+                        for (String k : optSet.keySet()) {
+                            if (k.startsWith(name))
+                                names.add(k);
+                        }
+                    }
+
+                    switch (names.size()) {
+                    case 1:
+                        name = names.get(0);
+                        optSet.put(name, true);
+                        if (optArg.containsKey(name)) {
+                            if (value != null)
+                                addArg(name, value);
+                            else
+                                needArg = name;
+                        }
+                        else if (value != null) {
+                            throw usageError("option '--" + name + "' doesn't allow an argument");
+                        }
+                        break;
+
+                    case 0:
+                        if (stopOnBadOption) {
+                            endOpt = true;
+                            xargs.add(oarg);
+                            break;
+                        }
+                        else
+                            throw usageError("invalid option '--" + name + "'");
+
+                    default:
+                        throw usageError("option '--" + name + "' is ambiguous: " + names);
+                    }
+                }
+                else {
+                    int i = 0;
+                    for (String c : arg.substring(1).split("")) {
+                        if (i++ == 0)
+                            continue;
+                        if (optName.containsKey(c)) {
+                            String name = optName.get(c);
+                            optSet.put(name, true);
+                            if (optArg.containsKey(name)) {
+                                if (i < arg.length()) {
+                                    addArg(name, arg.substring(i));
+                                }
+                                else {
+                                    needOpt = c;
+                                    needArg = name;
+                                }
+                                break;
+                            }
+                        }
+                        else {
+                            if (stopOnBadOption) {
+                                xargs.add("-" + c);
+                                endOpt = true;
+                            }
+                            else
+                                throw usageError("invalid option '" + c + "'");
+                        }
+                    }
+                }
+            }
+        }
+
+        if (needArg != null) {
+            String name = (needOpt != null) ? needOpt : "--" + needArg;
+            throw usageError("option '" + name + "' requires an argument");
+        }
+
+        // remove long option aliases
+        for (Entry<String, String> alias : optAlias.entrySet()) {
+            if (optSet.get(alias.getKey())) {
+                optSet.put(alias.getValue(), true);
+                if (optArg.containsKey(alias.getKey()))
+                    optArg.put(alias.getValue(), optArg.get(alias.getKey()));
+            }
+            optSet.remove(alias.getKey());
+            optArg.remove(alias.getKey());
+        }
+
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "isSet" + optSet + "\nArg" + optArg + "\nargs" + xargs;
+    }
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Activator.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Activator.java
new file mode 100644
index 0000000..4a723f3
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Activator.java
@@ -0,0 +1,151 @@
+/*
+ * 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.shell;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.command.CommandProcessor;
+import org.osgi.service.command.CommandSession;
+import org.osgi.service.command.Converter;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator, Runnable
+{
+    private ServiceTracker commandProcessorTracker;
+    private Set<ServiceRegistration> regs = new HashSet<ServiceRegistration>();
+    private CommandSession session;
+    private Shell shell;
+    private Thread thread;
+
+    public void start(final BundleContext context) throws Exception
+    {
+        shell = new Shell(context);
+        registerCommands(context);
+        commandProcessorTracker = processorTracker(context);
+    }
+
+    public void stop(BundleContext context) throws Exception
+    {
+        if (thread != null)
+        {
+            thread.interrupt();
+        }
+
+        commandProcessorTracker.close();
+        
+        Iterator<ServiceRegistration> iterator = regs.iterator();
+        while (iterator.hasNext())
+        {
+            ServiceRegistration reg = iterator.next();
+            reg.unregister();
+            iterator.remove();
+        }
+    }
+
+    public void run()
+    {
+        try
+        {
+            Thread.sleep(100);    // wait for gosh command to be registered
+            String args = System.getProperty("gosh.args", "");
+            session.execute("gosh --login " + args);
+        }
+        catch (Exception e)
+        {
+            Object loc = session.get(".location");
+            if (null == loc || !loc.toString().contains(":"))
+            {
+                loc = "gogo";
+            }
+
+            System.err.println(loc + ": " + e.getClass().getSimpleName() + ": " + e.getMessage());
+            e.printStackTrace();
+        }
+        finally
+        {
+            session.close();
+        }
+    }
+
+    private void startShell(CommandProcessor processor)
+    {
+        session = processor.createSession(System.in, System.out, System.err);
+        shell.setProcessor(processor);
+        thread = new Thread(this, "Gogo shell");
+        thread.start();
+    }
+
+    private void registerCommands(BundleContext context)
+    {
+        // default converters
+        regs.add(context.registerService(Converter.class.getName(), new Converters(context), null));
+        
+        Dictionary<String, Object> dict = new Hashtable<String, Object>();
+        dict.put(CommandProcessor.COMMAND_SCOPE, "gogo");
+
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Shell.functions);
+        regs.add(context.registerService(Shell.class.getName(), shell, dict));
+
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Builtin.functions);
+        regs.add(context.registerService(Builtin.class.getName(), new Builtin(), dict));
+
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Procedural.functions);
+        regs.add(context.registerService(Procedural.class.getName(), new Procedural(), dict));
+
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Posix.functions);
+        regs.add(context.registerService(Posix.class.getName(), new Posix(), dict));
+    }
+
+    private ServiceTracker processorTracker(BundleContext context)
+    {
+        ServiceTracker t = new ServiceTracker(context, CommandProcessor.class.getName(),
+            null)
+        {
+            @Override
+            public Object addingService(ServiceReference reference)
+            {
+                CommandProcessor processor = (CommandProcessor) super.addingService(reference);
+                startShell(processor);
+                return processor;
+            }
+
+            @Override
+            public void removedService(ServiceReference reference, Object service)
+            {
+                if (thread != null)
+                {
+                    thread.interrupt();
+                }
+                super.removedService(reference, service);
+            }
+        };
+
+        t.open();
+        return t;
+    }
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Builtin.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Builtin.java
new file mode 100644
index 0000000..f66a0ae
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Builtin.java
@@ -0,0 +1,596 @@
+/*
+ * 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.shell;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Map.Entry;
+
+import org.apache.felix.gogo.options.Option;
+import org.apache.felix.gogo.options.Options;
+import org.osgi.service.command.CommandSession;
+import org.osgi.service.command.Converter;
+
+/**
+ * gosh built-in commands.
+ */
+public class Builtin
+{
+
+    static final String[] functions = { "format", "getopt", "new", "set", "tac", "type" };
+
+    private static final String[] packages = { "java.lang", "java.io", "java.net",
+            "java.util" };
+
+    public CharSequence format(CommandSession session)
+    {
+        return format(session, session.get("_"));    // last result
+    }
+    
+    public CharSequence format(CommandSession session, Object arg)
+    {
+        CharSequence result = session.format(arg, Converter.INSPECT);
+        System.out.println(result);
+        return result;
+    }
+
+    /**
+     * script access to Options.
+     */
+    public Option getopt(List<Object> spec, Object[] args)
+    {
+        String[] optSpec = new String[spec.size()];
+        for (int i = 0; i < optSpec.length; ++i)
+        {
+            optSpec[i] = spec.get(i).toString();
+        }
+        return Options.compile(optSpec).parse(args);
+    }
+
+    // FIXME: the "new" command should be provided by runtime,
+    // so it can leverage same argument coercion mechanism, used to invoke methods.
+    public Object _new(Object name, Object[] argv) throws Exception
+    {
+        Class<?> clazz = null;
+
+        if (name instanceof Class<?>)
+        {
+            clazz = (Class<?>) name;
+        }
+        else
+        {
+            clazz = loadClass(name.toString());
+        }
+
+        for (Constructor<?> c : clazz.getConstructors())
+        {
+            Class<?>[] types = c.getParameterTypes();
+            if (types.length != argv.length)
+            {
+                continue;
+            }
+
+            boolean match = true;
+
+            for (int i = 0; i < argv.length; ++i)
+            {
+                if (!types[i].isAssignableFrom(argv[i].getClass()))
+                {
+                    if (!types[i].isAssignableFrom(String.class))
+                    {
+                        match = false;
+                        break;
+                    }
+                    argv[i] = argv[i].toString();
+                }
+            }
+
+            if (!match)
+            {
+                continue;
+            }
+
+            try
+            {
+                return c.newInstance(argv);
+            }
+            catch (InvocationTargetException ite)
+            {
+                Throwable cause = ite.getCause();
+                if (cause instanceof Exception)
+                {
+                    throw (Exception) cause;
+                }
+                throw ite;
+            }
+        }
+
+        throw new IllegalArgumentException("can't coerce " + Arrays.asList(argv)
+            + " to any of " + Arrays.asList(clazz.getConstructors()));
+    }
+
+    private Class<?> loadClass(String name) throws ClassNotFoundException
+    {
+        if (!name.contains("."))
+        {
+            for (String p : packages)
+            {
+                String pkg = p + "." + name;
+                try
+                {
+                    return Class.forName(pkg);
+                }
+                catch (ClassNotFoundException e)
+                {
+                }
+            }
+        }
+        return Class.forName(name);
+    }
+
+    public void set(CommandSession session, String[] argv) throws Exception
+    {
+        final String[] usage = {
+                "set - show session variables",
+                "Usage: set [OPTIONS] [PREFIX]",
+                "  -? --help                show help",
+                "  -a --all                 show all variables, including those starting with .",
+                "  -x                       set xtrace option",
+                "  +x                       unset xtrace option",
+                "If PREFIX given, then only show variable(s) starting with PREFIX" };
+
+        Option opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help"))
+        {
+            opt.usage();
+            return;
+        }
+
+        List<String> args = opt.args();
+        String prefix = (args.isEmpty() ? "" : args.get(0));
+
+        if (opt.isSet("x"))
+        {
+            session.put("echo", true);
+        }
+        else if ("+x".equals(prefix))
+        {
+            session.put("echo", null);
+        }
+        else
+        {
+            boolean all = opt.isSet("all");
+            for (String key : new TreeSet<String>(Shell.getVariables(session)))
+            {
+                if (!key.startsWith(prefix))
+                    continue;
+
+                if (key.startsWith(".") && !(all || prefix.length() > 0))
+                    continue;
+
+                Object target = session.get(key);
+                String type = null;
+                String value = null;
+
+                if (target != null)
+                {
+                    Class<? extends Object> clazz = target.getClass();
+                    type = clazz.getSimpleName();
+                    value = target.toString();
+                }
+
+                String trunc = value == null || value.length() < 55 ? "" : "...";
+                System.out.println(String.format("%-15.15s %-15s %.45s%s", type, key,
+                    value, trunc));
+            }
+        }
+    }
+
+    public Object tac(CommandSession session, String[] argv) throws IOException
+    {
+        final String[] usage = {
+                "tac - capture stdin as String or List and optionally write to file.",
+                "Usage: tac [-al] [FILE]", "  -a --append              append to FILE",
+                "  -l --list                return List<String>",
+                "  -? --help                show help" };
+
+        Option opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help"))
+        {
+            opt.usage();
+            return null;
+        }
+
+        List<String> args = opt.args();
+        BufferedWriter fw = null;
+
+        if (args.size() == 1)
+        {
+            String path = args.get(0);
+            File file = new File(Shell.cwd(session).resolve(path));
+            fw = new BufferedWriter(new FileWriter(file, opt.isSet("append")));
+        }
+
+        StringWriter sw = new StringWriter();
+        BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
+
+        ArrayList<String> list = null;
+
+        if (opt.isSet("list"))
+        {
+            list = new ArrayList<String>();
+        }
+
+        boolean first = true;
+        String s;
+
+        while ((s = rdr.readLine()) != null)
+        {
+            if (list != null)
+            {
+                list.add(s);
+            }
+            else
+            {
+                if (!first)
+                {
+                    sw.write(' ');
+                }
+                first = false;
+                sw.write(s);
+            }
+
+            if (fw != null)
+            {
+                fw.write(s);
+                fw.newLine();
+            }
+        }
+
+        if (fw != null)
+        {
+            fw.close();
+        }
+
+        return list != null ? list : sw.toString();
+    }
+
+    // FIXME: expose API in runtime so type command doesn't have to duplicate the runtime
+    // command search strategy.
+    public boolean type(CommandSession session, String[] argv) throws Exception
+    {
+        final String[] usage = { "type - show command type",
+                "Usage: type [OPTIONS] [name[:]]",
+                "  -a --all                 show all matches",
+                "  -? --help                show help",
+                "  -q --quiet               don't print anything, just return status",
+                "  -s --scope=NAME          list all commands in named scope",
+                "  -t --types               show full java type names" };
+
+        Option opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help"))
+        {
+            opt.usage();
+            return true;
+        }
+        
+        boolean all = opt.isSet("all");
+
+        String optScope = null;
+        if (opt.isSet("scope"))
+        {
+            optScope = opt.get("scope");
+        }
+
+        if (args.size() == 1)
+        {
+            String arg = args.get(0);
+            if (arg.endsWith(":"))
+            {
+                optScope = args.remove(0);
+            }
+        }
+
+        if (optScope != null || (args.isEmpty() && all))
+        {
+            Set<String> snames = new TreeSet<String>();
+
+            for (String sname : (getCommands(session)))
+            {
+                if ((optScope == null) || sname.startsWith(optScope))
+                {
+                    snames.add(sname);
+                }
+            }
+
+            for (String sname : snames)
+            {
+                System.out.println(sname);
+            }
+
+            return true;
+        }
+
+        if (args.size() == 0)
+        {
+            Map<String, Integer> scopes = new TreeMap<String, Integer>();
+
+            for (String sname : getCommands(session))
+            {
+                int colon = sname.indexOf(':');
+                String scope = sname.substring(0, colon);
+                Integer count = scopes.get(scope);
+                if (count == null)
+                {
+                    count = 0;
+                }
+                scopes.put(scope, ++count);
+            }
+
+            for (Entry<String, Integer> entry : scopes.entrySet())
+            {
+                System.out.println(entry.getKey() + ":" + entry.getValue());
+            }
+
+            return true;
+        }
+
+        final String name = args.get(0).toLowerCase();
+
+        final int colon = name.indexOf(':');
+        final String MAIN = "_main"; // FIXME: must match Reflective.java
+
+        StringBuilder buf = new StringBuilder();
+        Set<String> cmds = new LinkedHashSet<String>();
+
+        // get all commands
+        if ((colon != -1) || (session.get(name) != null))
+        {
+            cmds.add(name);
+        }
+        else if (session.get(MAIN) != null)
+        {
+            cmds.add(MAIN);
+        }
+        else
+        {
+            String path = session.get("SCOPE") != null ? session.get("SCOPE").toString()
+                : "*";
+
+            for (String s : path.split(":"))
+            {
+                if (s.equals("*"))
+                {
+                    for (String sname : getCommands(session))
+                    {
+                        if (sname.endsWith(":" + name))
+                        {
+                            cmds.add(sname);
+                            if (!all)
+                            {
+                                break;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    String sname = s + ":" + name;
+                    if (session.get(sname) != null)
+                    {
+                        cmds.add(sname);
+                        if (!all)
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        for (String key : cmds)
+        {
+            Object target = session.get(key);
+            if (target == null)
+            {
+                continue;
+            }
+
+            CharSequence source = getClosureSource(session, key);
+
+            if (source != null)
+            {
+                buf.append(name);
+                buf.append(" is function {");
+                buf.append(source);
+                buf.append("}");
+                continue;
+            }
+
+            for (Method m : getMethods(session, key))
+            {
+                StringBuilder params = new StringBuilder();
+
+                for (Class<?> type : m.getParameterTypes())
+                {
+                    if (params.length() > 0)
+                    {
+                        params.append(", ");
+                    }
+                    params.append(type.getSimpleName());
+                }
+
+                String rtype = m.getReturnType().getSimpleName();
+
+                if (buf.length() > 0)
+                {
+                    buf.append("\n");
+                }
+
+                if (opt.isSet("types"))
+                {
+                    String cname = m.getDeclaringClass().getName();
+                    buf.append(String.format("%s %s.%s(%s)", rtype, cname, m.getName(),
+                        params));
+                }
+                else
+                {
+                    buf.append(String.format("%s is %s %s(%s)", name, rtype, key, params));
+                }
+            }
+        }
+
+        if (buf.length() > 0)
+        {
+            if (!opt.isSet("quiet"))
+            {
+                System.out.println(buf);
+            }
+            return true;
+        }
+
+        if (!opt.isSet("quiet"))
+        {
+            System.err.println("type: " + name + " not found.");
+        }
+
+        return false;
+    }
+
+    /*
+     * the following methods depend on the internals of the runtime implementation.
+     * ideally, they should be available via some API.
+     */
+
+    @SuppressWarnings("unchecked")
+    static Set<String> getCommands(CommandSession session)
+    {
+        return (Set<String>) session.get(".commands");
+    }
+
+    private boolean isClosure(Object target)
+    {
+        return target.getClass().getSimpleName().equals("Closure");
+    }
+
+    private boolean isCommand(Object target)
+    {
+        return target.getClass().getSimpleName().equals("CommandProxy");
+    }
+
+    private CharSequence getClosureSource(CommandSession session, String name)
+        throws Exception
+    {
+        Object target = session.get(name);
+
+        if (target == null)
+        {
+            return null;
+        }
+
+        if (!isClosure(target))
+        {
+            return null;
+        }
+
+        Field sourceField = target.getClass().getDeclaredField("source");
+        sourceField.setAccessible(true);
+        return (CharSequence) sourceField.get(target);
+    }
+
+    private List<Method> getMethods(CommandSession session, String scmd) throws Exception
+    {
+        final int colon = scmd.indexOf(':');
+        final String function = colon == -1 ? scmd : scmd.substring(colon + 1);
+        final String name = KEYWORDS.contains(function) ? ("_" + function) : function;
+        final String get = "get" + function;
+        final String is = "is" + function;
+        final String set = "set" + function;
+        final String MAIN = "_main"; // FIXME: must match Reflective.java
+
+        Object target = session.get(scmd);
+        if (target == null)
+        {
+            return null;
+        }
+
+        if (isClosure(target))
+        {
+            return null;
+        }
+
+        if (isCommand(target))
+        {
+            Method method = target.getClass().getMethod("getTarget", (Class[])null);
+            method.setAccessible(true);
+            target = method.invoke(target, (Object[])null);
+        }
+
+        ArrayList<Method> list = new ArrayList<Method>();
+        Class<?> tc = (target instanceof Class<?>) ? (Class<?>) target
+            : target.getClass();
+        Method[] methods = tc.getMethods();
+
+        for (Method m : methods)
+        {
+            String mname = m.getName().toLowerCase();
+
+            if (mname.equals(name) || mname.equals(get) || mname.equals(set)
+                || mname.equals(is) || mname.equals(MAIN))
+            {
+                list.add(m);
+            }
+        }
+
+        return list;
+    }
+
+    private final static Set<String> KEYWORDS = new HashSet<String>(
+        Arrays.asList(new String[] { "abstract", "continue", "for", "new", "switch",
+                "assert", "default", "goto", "package", "synchronized", "boolean", "do",
+                "if", "private", "this", "break", "double", "implements", "protected",
+                "throw", "byte", "else", "import", "public", "throws", "case", "enum",
+                "instanceof", "return", "transient", "catch", "extends", "int", "short",
+                "try", "char", "final", "interface", "static", "void", "class",
+                "finally", "long", "strictfp", "volatile", "const", "float", "native",
+                "super", "while" }));
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Console.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Console.java
new file mode 100644
index 0000000..6b0bca4
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Console.java
@@ -0,0 +1,147 @@
+/*
+ * 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.shell;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import org.osgi.service.command.CommandSession;
+import org.osgi.service.command.Converter;
+
+public class Console implements Runnable
+{
+    private final CommandSession session;
+    private final InputStream in;
+    private final PrintStream out;
+    private boolean quit;
+
+    public Console(CommandSession session)
+    {
+        this.session = session;
+        in = session.getKeyboard();
+        out = session.getConsole();
+    }
+
+    public void run()
+    {
+        try
+        {
+            while (!quit)
+            {
+                try
+                {
+                    Object prompt = session.get("prompt");
+                    if (prompt == null)
+                    {
+                        prompt = "g! ";
+                    }
+
+                    CharSequence line = getLine(prompt.toString());
+
+                    if (line == null)
+                    {
+                        break;
+                    }
+
+                    Object result = session.execute(line);
+                    session.put("_", result);    // set $_ to last result
+
+                    if (result != null && !Boolean.FALSE.equals(session.get(".Gogo.format")))
+                    {
+                        out.println(session.format(result, Converter.INSPECT));
+                    }
+                }
+                catch (Throwable e)
+                {
+                    if (!quit)
+                    {
+                        session.put("exception", e);
+                        Object loc = session.get(".location");
+
+                        if (null == loc || !loc.toString().contains(":"))
+                        {
+                            loc = "gogo";
+                        }
+
+                        out.println(loc + ": " + e.getClass().getSimpleName() + ": " + e.getMessage());
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            if (!quit)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private CharSequence getLine(String prompt) throws IOException
+    {
+        StringBuilder sb = new StringBuilder();
+        out.print(prompt);
+
+        while (!quit)
+        {
+            out.flush();
+            int c = in.read();
+
+            switch (c)
+            {
+                case -1:
+                case 4:    // EOT, ^D from telnet
+                    quit = true;
+                    break;
+
+                case '\r':
+                    break;
+
+                case '\n':
+                    if (sb.length() > 0)
+                    {
+                        return sb;
+                    }
+                    out.print(prompt);
+                    break;
+
+                case '\b':
+                    if (sb.length() > 0)
+                    {
+                        out.print("\b \b");
+                        sb.deleteCharAt(sb.length() - 1);
+                    }
+                    break;
+
+                default:
+                    sb.append((char) c);
+                    break;
+            }
+        }
+
+        return null;
+    }
+
+    public void close()
+    {
+        quit = true;
+    }
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Converters.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Converters.java
new file mode 100644
index 0000000..55aa871
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Converters.java
@@ -0,0 +1,292 @@
+/*
+ * 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.shell;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.Formatter;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.command.Converter;
+import org.osgi.service.command.Function;
+import org.osgi.service.startlevel.StartLevel;
+
+public class Converters implements Converter
+{
+    private final BundleContext context;
+    public Converters(BundleContext context)
+    {
+        this.context = context;
+    }
+
+    private CharSequence print(Bundle bundle)
+    {
+        // [ ID ] [STATE      ] [ SL ] symname
+        StartLevel sl = null;
+        ServiceReference ref = context.getServiceReference(StartLevel.class.getName());
+        if (ref != null)
+        {
+            sl = (StartLevel) context.getService(ref);
+        }
+
+        if (sl == null)
+        {
+            return String.format("%5d|%-11s|%s (%s)", bundle.getBundleId(),
+                getState(bundle), bundle.getSymbolicName(), bundle.getVersion());
+        }
+
+        int level = sl.getBundleStartLevel(bundle);
+        context.ungetService(ref);
+
+        return String.format("%5d|%-11s|%5d|%s (%s)", bundle.getBundleId(),
+            getState(bundle), level, bundle.getSymbolicName(), bundle.getVersion());
+    }
+
+    private CharSequence print(ServiceReference ref)
+    {
+        StringBuilder sb = new StringBuilder();
+        Formatter f = new Formatter(sb);
+
+        String spid = "";
+        Object pid = ref.getProperty("service.pid");
+        if (pid != null)
+        {
+            spid = pid.toString();
+        }
+
+        f.format("%06d %3s %-40s %s", ref.getProperty("service.id"),
+            ref.getBundle().getBundleId(),
+            getShortNames((String[]) ref.getProperty("objectclass")), spid);
+        return sb;
+    }
+
+    private CharSequence getShortNames(String[] list)
+    {
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        for (String s : list)
+        {
+            sb.append(del + getShortName(s));
+            del = " | ";
+        }
+        return sb;
+    }
+
+    private CharSequence getShortName(String name)
+    {
+        int n = name.lastIndexOf('.');
+        if (n < 0)
+        {
+            n = 0;
+        }
+        else
+        {
+            n++;
+        }
+        return name.subSequence(n, name.length());
+    }
+
+    private String getState(Bundle bundle)
+    {
+        switch (bundle.getState())
+        {
+            case Bundle.ACTIVE:
+                return "Active";
+
+            case Bundle.INSTALLED:
+                return "Installed";
+
+            case Bundle.RESOLVED:
+                return "Resolved";
+
+            case Bundle.STARTING:
+                return "Starting";
+
+            case Bundle.STOPPING:
+                return "Stopping";
+
+            case Bundle.UNINSTALLED:
+                return "Uninstalled ";
+        }
+        return null;
+    }
+
+    public Bundle bundle(Bundle i)
+    {
+        return i;
+    }
+
+    public Object convert(Class<?> desiredType, final Object in) throws Exception
+    {
+        if (desiredType == Bundle.class)
+        {
+            return convertBundle(in);
+        }
+
+        if (desiredType == ServiceReference.class)
+        {
+            return convertServiceReference(in);
+        }
+
+        if (desiredType == Class.class)
+        {
+            try
+            {
+                return Class.forName(in.toString());
+            }
+            catch (ClassNotFoundException e)
+            {
+                return null;
+            }
+        }
+
+        if (desiredType.isAssignableFrom(String.class) && in instanceof InputStream)
+        {
+            return read(((InputStream) in));
+        }
+
+        if (in instanceof Function && desiredType.isInterface()
+            && desiredType.getDeclaredMethods().length == 1)
+        {
+            return Proxy.newProxyInstance(desiredType.getClassLoader(),
+                new Class[] { desiredType }, new InvocationHandler()
+                {
+                    Function command = ((Function) in);
+
+                    public Object invoke(Object proxy, Method method, Object[] args)
+                        throws Throwable
+                    {
+                        return command.execute(null, Arrays.asList(args));
+                    }
+                });
+        }
+
+        return null;
+    }
+
+    private Object convertServiceReference(Object in) throws InvalidSyntaxException
+    {
+        String s = in.toString();
+        if (s.startsWith("(") && s.endsWith(")"))
+        {
+            ServiceReference refs[] = context.getServiceReferences(null, String.format(
+                "(|(service.id=%s)(service.pid=%s))", in, in));
+            if (refs != null && refs.length > 0)
+            {
+                return refs[0];
+            }
+        }
+
+        ServiceReference refs[] = context.getServiceReferences(null, String.format(
+            "(|(service.id=%s)(service.pid=%s))", in, in));
+        if (refs != null && refs.length > 0)
+        {
+            return refs[0];
+        }
+        return null;
+    }
+
+    private Object convertBundle(Object in)
+    {
+        String s = in.toString();
+        try
+        {
+            long id = Long.parseLong(s);
+            return context.getBundle(id);
+        }
+        catch (NumberFormatException nfe)
+        {
+            // Ignore
+        }
+
+        Bundle bundles[] = context.getBundles();
+        for (Bundle b : bundles)
+        {
+            if (b.getLocation().equals(s))
+            {
+                return b;
+            }
+
+            if (b.getSymbolicName().equals(s))
+            {
+                return b;
+            }
+        }
+
+        return null;
+    }
+
+    public CharSequence format(Object target, int level, Converter converter)
+        throws IOException
+    {
+        if (level == INSPECT && target instanceof InputStream)
+        {
+            return read(((InputStream) target));
+        }
+        if (level == LINE && target instanceof Bundle)
+        {
+            return print((Bundle) target);
+        }
+        if (level == LINE && target instanceof ServiceReference)
+        {
+            return print((ServiceReference) target);
+        }
+        if (level == PART && target instanceof Bundle)
+        {
+            return ((Bundle) target).getSymbolicName();
+        }
+        if (level == PART && target instanceof ServiceReference)
+        {
+            return getShortNames((String[]) ((ServiceReference) target).getProperty("objectclass"));
+        }
+        return null;
+    }
+
+    private CharSequence read(InputStream in) throws IOException
+    {
+        int c;
+        StringBuffer sb = new StringBuffer();
+        while ((c = in.read()) > 0)
+        {
+            if (c >= 32 && c <= 0x7F || c == '\n' || c == '\r')
+            {
+                sb.append((char) c);
+            }
+            else
+            {
+                String s = Integer.toHexString(c).toUpperCase();
+                sb.append("\\");
+                if (s.length() < 1)
+                {
+                    sb.append(0);
+                }
+                sb.append(s);
+            }
+        }
+        return sb;
+    }
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Posix.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Posix.java
new file mode 100644
index 0000000..389dca7
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Posix.java
@@ -0,0 +1,203 @@
+/*
+ * 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.shell;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.gogo.options.Option;
+import org.apache.felix.gogo.options.Options;
+import org.osgi.service.command.CommandSession;
+
+/**
+ * Posix-like utilities.
+ * 
+ * @see http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html
+ */
+public class Posix
+{
+    static final String[] functions = { "cat", "echo", "grep" };
+
+    public void cat(CommandSession session, String[] args) throws Exception
+    {
+        if (args.length == 0)
+        {
+            copy(System.in, System.out);
+            return;
+        }
+
+        URI cwd = Shell.cwd(session);
+        
+        for (String arg : args)
+        {
+            copy(cwd.resolve(arg), System.out);
+        }
+    }
+
+    public void echo(Object[] args)
+    {
+        StringBuilder buf = new StringBuilder();
+
+        if (args == null)
+        {
+            System.out.println("Null");
+            return;
+        }
+
+        for (Object arg : args)
+        {
+            if (buf.length() > 0)
+                buf.append(' ');
+            buf.append(String.valueOf(arg));
+        }
+
+        System.out.println(buf);
+    }
+
+    public boolean grep(CommandSession session, String[] argv) throws IOException
+    {
+        final String[] usage = {
+                "grep -  search for PATTERN in each FILE or standard input.",
+                "Usage: grep [OPTIONS] PATTERN [FILES]",
+                "  -? --help                show help",
+                "  -i --ignore-case         ignore case distinctions",
+                "  -n --line-number         prefix each line with line number within its input file",
+                "  -q --quiet, --silent     suppress all normal output",
+                "  -v --invert-match        select non-matching lines" };
+
+        Option opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help"))
+        {
+            opt.usage();
+            return true;
+        }
+
+        List<String> args = opt.args();
+
+        if (args.size() == 0)
+        {
+            throw opt.usageError("no pattern supplied.");
+        }
+
+        String regex = args.remove(0);
+        if (opt.isSet("ignore-case"))
+        {
+            regex = "(?i)" + regex;
+        }
+
+        if (args.isEmpty())
+        {
+            args.add(null);
+        }
+
+        StringBuilder buf = new StringBuilder();
+
+        if (args.size() > 1)
+        {
+            buf.append("%1$s:");
+        }
+
+        if (opt.isSet("line-number"))
+        {
+            buf.append("%2$s:");
+        }
+
+        buf.append("%3$s");
+        String format = buf.toString();
+
+        Pattern pattern = Pattern.compile(regex);
+        boolean status = true;
+        boolean match = false;
+
+        for (String arg : args)
+        {
+            InputStream in = null;
+
+            try
+            {
+                URI cwd = Shell.cwd(session);
+                in = (arg == null) ? System.in : cwd.resolve(arg).toURL().openStream();
+                
+                BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
+                int line = 0;
+                String s;
+                while ((s = rdr.readLine()) != null)
+                {
+                    line++;
+                    Matcher matcher = pattern.matcher(s);
+                    if (!(matcher.find() ^ !opt.isSet("invert-match")))
+                    {
+                        match = true;
+                        if (opt.isSet("quiet"))
+                            break;
+
+                        System.out.println(String.format(format, arg, line, s));
+                    }
+                }
+
+                if (match && opt.isSet("quiet"))
+                {
+                    break;
+                }
+            }
+            catch (IOException e)
+            {
+                System.err.println("grep: " + e.getMessage());
+                status = false;
+            }
+            finally
+            {
+                if (arg != null && in != null)
+                {
+                    in.close();
+                }
+            }
+        }
+
+        return match && status;
+    }
+    
+    public static void copy(URI source, OutputStream out) throws IOException {
+        InputStream in = source.toURL().openStream();
+        try {
+            copy(in, out);
+        } finally {
+            in.close();
+        }
+    }
+
+
+    public static void copy(InputStream in, OutputStream out) throws IOException {
+        byte buf[] = new byte[10240];
+        int len;
+        while ((len = in.read(buf)) > 0) {
+            out.write(buf, 0, len);
+        }
+        out.flush();
+    }
+
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Procedural.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Procedural.java
new file mode 100644
index 0000000..4821ef26
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Procedural.java
@@ -0,0 +1,189 @@
+/*
+ * 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.shell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.osgi.service.command.CommandSession;
+import org.osgi.service.command.Function;
+
+public class Procedural
+{
+    static final String[] functions = { "each", "if", "not", "throw", "try", "until",
+            "while" };
+
+    public List<Object> each(CommandSession session, Collection<Object> list,
+        Function closure) throws Exception
+    {
+        List<Object> args = new ArrayList<Object>();
+        List<Object> results = new ArrayList<Object>();
+        args.add(null);
+
+        for (Object x : list)
+        {
+            checkInterrupt();
+            args.set(0, x);
+            results.add(closure.execute(session, args));
+        }
+
+        return results;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object _if(CommandSession session, Function[] fns) throws Exception
+    {
+        int length = fns.length;
+        if (length < 2)
+        {
+            throw new IllegalArgumentException(
+                "Usage: if {condition} {if-action} ... {else-action}");
+        }
+
+        List<Object> args = (List<Object>) session.get("args");
+
+        for (int i = 0; i < length; ++i)
+        {
+            if (i == length - 1 || isTrue(fns[i++].execute(session, args)))
+            {
+                return fns[i].execute(session, args);
+            }
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean not(CommandSession session, Function condition) throws Exception
+    {
+        if (null == condition)
+        {
+            return true;
+        }
+        
+        List<Object> args = (List<Object>) session.get("args");
+        return !isTrue(condition.execute(session, args));
+    }
+
+    // Reflective.coerce() prefers to construct a new Throwable(String)
+    // than to call this method directly.
+    public void _throw(String message)
+    {
+        throw new IllegalArgumentException(message);
+    }
+
+    public void _throw(Exception e) throws Exception
+    {
+        throw e;
+    }
+
+    public void _throw(CommandSession session) throws Throwable
+    {
+        Object exception = session.get("exception");
+        if (exception instanceof Throwable)
+            throw (Throwable) exception;
+        else
+            throw new IllegalArgumentException("exception not set or not Throwable.");
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object _try(CommandSession session, Function func) throws Exception
+    {
+        List<Object> args = (List<Object>) session.get("args");
+        try
+        {
+            return func.execute(session, args);
+        }
+        catch (Exception e)
+        {
+            session.put("exception", e);
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object _try(CommandSession session, Function func, Function error)
+        throws Exception
+    {
+        List<Object> args = (List<Object>) session.get("args");
+        try
+        {
+            return func.execute(session, args);
+        }
+        catch (Exception e)
+        {
+            session.put("exception", e);
+            return error.execute(session, args);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void _while(CommandSession session, Function condition, Function ifTrue)
+        throws Exception
+    {
+        List<Object> args = (List<Object>) session.get("args");
+        while (isTrue(condition.execute(session, args)))
+        {
+            ifTrue.execute(session, args);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void until(CommandSession session, Function condition, Function ifTrue)
+        throws Exception
+    {
+        List<Object> args = (List<Object>) session.get("args");
+        while (!isTrue(condition.execute(session, args)))
+        {
+            ifTrue.execute(session, args);
+        }
+    }
+
+    private boolean isTrue(Object result) throws InterruptedException
+    {
+        checkInterrupt();
+
+        if (result == null)
+            return false;
+
+        if (result instanceof Boolean)
+            return ((Boolean) result).booleanValue();
+
+        if (result instanceof Number)
+        {
+            if (0 == ((Number) result).intValue())
+                return false;
+        }
+
+        if ("".equals(result))
+            return false;
+
+        if ("0".equals(result))
+            return false;
+
+        return true;
+    }
+    
+    private void checkInterrupt() throws InterruptedException
+    {
+        if (Thread.currentThread().isInterrupted())
+            throw new InterruptedException("loop interrupted");
+    }
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Shell.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Shell.java
new file mode 100644
index 0000000..e7e3d5d
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Shell.java
@@ -0,0 +1,260 @@
+/*
+ * 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.shell;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URLConnection;
+import java.nio.CharBuffer;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.gogo.options.Option;
+import org.apache.felix.gogo.options.Options;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.service.command.CommandProcessor;
+import org.osgi.service.command.CommandSession;
+
+public class Shell
+{
+    static final String[] functions = { "gosh", "sh", "shutdown", "source", "telnetd" };
+
+    private final static URI CWD = new File(".").toURI();
+
+    private final URI baseURI;
+    private final BundleContext context;
+
+    private CommandProcessor processor;
+    private Telnet telnet;
+
+    public Shell(BundleContext context)
+    {
+        this.context = context;
+        String baseDir = System.getProperty("gosh.home", System.getProperty("user.dir"));
+        baseURI = new File(baseDir).toURI();
+    }
+
+    public void setProcessor(CommandProcessor processor)
+    {
+        this.processor = processor;
+    }
+
+    public Object gosh(final CommandSession session, String[] argv) throws Exception
+    {
+        final String[] usage = {
+                "gosh - execute script with arguments in a new session",
+                "  args are available as session variables $1..$9 and $args.",
+                "Usage: gosh [OPTIONS] [script-file [args..]]",
+                "  -c --command             pass all remaining args to sub-shell",
+                "     --login               login shell (same session, reads etc/gosh_profile)",
+                "  -s --noshutdown          don't shutdown framework when script completes",
+                "  -x --xtrace              echo commands before execution",
+                "  -? --help                show help",
+                "If no script-file, an interactive shell is started, type $D to exit." };
+
+        Option opt = Options.compile(usage).setOptionsFirst(true).parse(argv);
+        List<String> args = opt.args();
+
+        boolean login = opt.isSet("login");
+
+        if (opt.isSet("help"))
+        {
+            opt.usage();
+            if (login && !opt.isSet("noshutdown"))
+            {
+                shutdown();
+            }
+            return null;
+        }
+
+        if (opt.isSet("command") && args.isEmpty())
+        {
+            throw opt.usageError("option --command requires argument(s)");
+        }
+
+        CommandSession newSession = (login ? session : processor.createSession(
+            session.getKeyboard(), session.getConsole(), System.err));
+
+        if (opt.isSet("xtrace"))
+        {
+            newSession.put("echo", true);
+        }
+
+        if (login)
+        {
+            URI uri = baseURI.resolve("etc/gosh_profile");
+            if (!new File(uri).exists())
+            {
+                uri = getClass().getResource("/gosh_profile").toURI();
+            }
+            if (uri != null)
+            {
+                source(session, uri.toString());
+            }
+        }
+
+        // export variables starting with upper-case to newSession
+        for (String key : getVariables(session))
+        {
+            if (key.matches("[.]?[A-Z].*"))
+            {
+                newSession.put(key, session.get(key));
+            }
+        }
+
+        Object result;
+
+        if (args.isEmpty())
+        {
+            result = console(newSession);
+        }
+        else
+        {
+            CharSequence program;
+
+            if (opt.isSet("command"))
+            {
+                StringBuilder buf = new StringBuilder();
+                for (String arg : args)
+                {
+                    if (buf.length() > 0)
+                    {
+                        buf.append(' ');
+                    }
+                    buf.append(arg);
+                }
+                program = buf;
+            }
+            else
+            {
+                URI script = cwd(session).resolve(args.remove(0));
+
+                // set script arguments
+                newSession.put("0", script);
+                newSession.put("args", args);
+
+                for (int i = 0; i < args.size(); ++i)
+                {
+                    newSession.put(String.valueOf(i + 1), args.get(i));
+                }
+
+                program = readScript(script);
+            }
+
+            result = newSession.execute(program);
+        }
+
+        if (login && !opt.isSet("noshutdown"))
+        {
+            shutdown();
+        }
+
+        return result;
+    }
+
+    public Object sh(final CommandSession session, String[] argv) throws Exception
+    {
+        return gosh(session, argv);
+    }
+
+    public void shutdown() throws BundleException
+    {
+        context.getBundle(0).stop();
+    }
+
+    public Object source(CommandSession session, String script) throws Exception
+    {
+        URI uri = cwd(session).resolve(script);
+        session.put("0", uri);
+        try
+        {
+            return session.execute(readScript(uri));
+        }
+        finally
+        {
+            session.put("0", null); // API doesn't support remove
+        }
+    }
+
+    public void telnetd(String[] argv) throws IOException
+    {
+        if (telnet == null)
+        {
+            telnet = new Telnet(processor);
+        }
+        telnet.telnetd(argv);
+    }
+
+    private Object console(CommandSession session)
+    {
+        Console console = new Console(session);
+        console.run();
+        return null;
+    }
+
+    private CharSequence readScript(URI script) throws Exception
+    {
+        URLConnection conn = script.toURL().openConnection();
+        int length = conn.getContentLength();
+
+        if (length == -1)
+        {
+            System.err.println("eek! unknown Contentlength for: " + script);
+            length = 10240;
+        }
+
+        InputStream in = conn.getInputStream();
+        CharBuffer cbuf = CharBuffer.allocate(length);
+        Reader reader = new InputStreamReader(in);
+        reader.read(cbuf);
+        in.close();
+        cbuf.rewind();
+
+        return cbuf;
+    }
+
+    @SuppressWarnings("unchecked")
+    static Set<String> getVariables(CommandSession session)
+    {
+        return (Set<String>) session.get(".variables");
+    }
+
+    static URI cwd(CommandSession session)
+    {
+        Object cwd = session.get("_cwd"); // _cwd is set by felixcommands:cd
+
+        if (cwd instanceof URI)
+        {
+            return (URI) cwd;
+        }
+        else if (cwd instanceof File)
+        {
+            return ((File) cwd).toURI();
+        }
+        else
+        {
+            return CWD;
+        }
+    }
+}
diff --git a/gogo/console/src/main/java/org/apache/felix/gogo/shell/Telnet.java b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Telnet.java
new file mode 100644
index 0000000..dd129df
--- /dev/null
+++ b/gogo/console/src/main/java/org/apache/felix/gogo/shell/Telnet.java
@@ -0,0 +1,185 @@
+/*
+ * 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.shell;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.List;
+
+import org.apache.felix.gogo.options.Option;
+import org.apache.felix.gogo.options.Options;
+import org.osgi.service.command.CommandProcessor;
+import org.osgi.service.command.CommandSession;
+
+/*
+ * a very simple Telnet server.
+ * real remote access should be via ssh.
+ */
+public class Telnet implements Runnable
+{
+    private static final int defaultPort = 2019;
+    private final CommandProcessor processor;
+    private ServerSocket server;
+    private Thread thread;
+    private boolean quit;
+    private int port;
+
+    public Telnet(CommandProcessor procesor)
+    {
+        this.processor = procesor;
+    }
+
+    public void telnetd(String[] argv) throws IOException
+    {
+        final String[] usage = { "telnetd - start simple telnet server",
+                "Usage: telnetd [-p port] start | stop | status",
+                "  -p --port=PORT           listen port (default=" + defaultPort + ")",
+                "  -? --help                show help" };
+
+        Option opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help") || args.isEmpty())
+        {
+            opt.usage();
+            return;
+        }
+
+        String command = args.get(0);
+
+        if ("start".equals(command))
+        {
+            if (server != null)
+            {
+                throw new IllegalStateException("telnetd is already running on port "
+                    + port);
+            }
+            port = opt.getNumber("port");
+            start();
+            status();
+        }
+        else if ("stop".equals(command))
+        {
+            if (server == null)
+            {
+                throw new IllegalStateException("telnetd is not running.");
+            }
+            stop();
+        }
+        else if ("status".equals(command))
+        {
+            status();
+        }
+        else
+        {
+            throw opt.usageError("bad command: " + command);
+        }
+    }
+
+    private void status()
+    {
+        if (server != null)
+        {
+            System.out.println("telnetd is running on port " + port);
+        }
+        else
+        {
+            System.out.println("telnetd is not running.");
+        }
+    }
+
+    private void start() throws IOException
+    {
+        quit = false;
+        server = new ServerSocket(port);
+        thread = new Thread(this, "gogo telnet");
+        thread.start();
+    }
+
+    private void stop() throws IOException
+    {
+        quit = true;
+        server.close();
+        server = null;
+        thread.interrupt();
+    }
+
+    public void run()
+    {
+        try
+        {
+            while (!quit)
+            {
+                final Socket socket = server.accept();
+                PrintStream out = new PrintStream(socket.getOutputStream());
+                final CommandSession session = processor.createSession(
+                    socket.getInputStream(), out, out);
+
+                Thread handler = new Thread()
+                {
+                    public void run()
+                    {
+                        try
+                        {
+                            session.execute("gosh --login --noshutdown");
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace();
+                        }
+                        finally
+                        {
+                            session.close();
+                            try
+                            {
+                                socket.close();
+                            }
+                            catch (IOException e)
+                            {
+                            }
+                        }
+                    }
+                };
+                handler.start();
+            }
+        }
+        catch (IOException e)
+        {
+            if (!quit)
+            {
+                e.printStackTrace();
+            }
+        }
+        finally
+        {
+            try
+            {
+                if (server != null)
+                {
+                    server.close();
+                }
+            }
+            catch (IOException e)
+            {
+            }
+        }
+    }
+}
diff --git a/gogo/console/src/main/resources/gosh_profile b/gogo/console/src/main/resources/gosh_profile
new file mode 100644
index 0000000..2219e25
--- /dev/null
+++ b/gogo/console/src/main/resources/gosh_profile
@@ -0,0 +1,36 @@
+# default gosh_profile
+# only read if etc/gosh_profile doesn't exist relative to the System property
+# gosh.home or failing that the current directory.
+
+# ensure gogo commands are found first
+SCOPE = gogo:*
+
+# add methods on BundleContext object as commands
+#addcommand context ${.context} (${.context} class)
+# bug: above invokes (String, Object, String) instead of (String, Object, Class)
+addcommand context ${.context}
+
+# add methods on System object as commands
+# FELIX-2335 prevents the use of (bundle 0) loadclass
+addcommand system ((bundle 1) loadclass java.lang.System)
+
+# alias to print full stack trace
+e = { $exception printStackTrace }
+
+## disable console auto-formatting of each result
+#  you will then need to explicitly use the 'format' command
+#  to print the result of commands that don't write to stdout.
+#.Gogo.format = false
+
+## disable printing the formatted result of a command into pipelines
+#.Format.Pipe = false
+
+# set prompt
+prompt = 'g! '
+
+# print welcome message
+try {
+  cat ($0 resolve motd)
+}
+
+# end
diff --git a/gogo/console/src/main/resources/motd b/gogo/console/src/main/resources/motd
new file mode 100644
index 0000000..7e26be1
--- /dev/null
+++ b/gogo/console/src/main/resources/motd
@@ -0,0 +1,4 @@
+_______________
+Welcome to Gogo
+Use 'type' to explore registered commands, 'type -?' for help.
+
