diff --git a/gogo/src/aQute/shell/console/Console.java b/gogo/src/aQute/shell/console/Console.java
new file mode 100644
index 0000000..a74ff8e
--- /dev/null
+++ b/gogo/src/aQute/shell/console/Console.java
@@ -0,0 +1,143 @@
+/*
+ * 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 aQute.shell.console;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+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.getKeybord());
+					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/src/aQute/shell/equinox/Equinox.java b/gogo/src/aQute/shell/equinox/Equinox.java
new file mode 100644
index 0000000..d2c34f1
--- /dev/null
+++ b/gogo/src/aQute/shell/equinox/Equinox.java
@@ -0,0 +1,389 @@
+package aQute.shell.equinox;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.command.*;
+import org.osgi.service.component.*;
+import org.osgi.service.log.*;
+import org.osgi.service.packageadmin.*;
+import org.osgi.service.startlevel.*;
+
+public class Equinox implements Converter {
+    BundleContext         context;
+    PackageAdmin          pka;
+    LogReaderService      lrs;
+    StartLevel            sls;
+    final static String[] functions = { "active", "bundles", "close", "diag",
+            "exec", "exit", "fork", "gc", "getprop", "headers", "init",
+            "install", "launch", "log", "packages", "packages", "refresh",
+            "services", "setbsl", "setfwsl", "setibsl", "setprop", "shutdown",
+            "sl", "ss", "start", "status", "stop", "uninstall", "update" };
+
+    protected void activate(ComponentContext context) {
+        this.context = context.getBundleContext();
+        Dictionary<String, Object> dict = new Hashtable<String, Object>();
+        dict.put(CommandProcessor.COMMAND_SCOPE, "eqx");
+        dict.put(CommandProcessor.COMMAND_FUNCTION, functions);
+        this.context.registerService( Converter.class.getName(), this, dict);
+    }
+
+    BundleContext getContext() {
+        return context;
+    }
+
+    public void setPka(PackageAdmin pka) {
+        this.pka = pka;
+    }
+
+    public void setLrs(LogReaderService lrs) {
+        this.lrs = lrs;
+    }
+
+    public void setSls(StartLevel sls) {
+        this.sls = sls;
+    }
+
+    /**
+     * - Displays unsatisfied constraints for the specified bundle(s).
+     */
+    public void diag() {
+    }
+
+    /*
+     * active - Displays a list of all bundles currently in the ACTIVE state.
+     */
+    public List<Bundle> active() {
+        List<Bundle> result = new ArrayList<Bundle>();
+        Bundle[] bundles = getContext().getBundles();
+        for (Bundle b : bundles) {
+            if (b.getState() == Bundle.ACTIVE)
+                result.add(b);
+        }
+        return result;
+    }
+
+    /*
+     * getprop { name } - Displays the system properties with the given name, or
+     * all of them.
+     */
+
+    public Object getprop(CharSequence name) {
+        if (name == null)
+            return System.getProperties();
+        else
+            return System.getProperty(name.toString());
+    }
+
+    /**
+     * launch - start the OSGi Framework
+     */
+
+    public void launch() {
+        throw new IllegalStateException("Already running");
+    }
+
+    /**
+     * shutdown - shutdown the OSGi Framework
+     */
+    public void shutdown() throws BundleException {
+        getContext().getBundle().stop();
+    }
+
+    /**
+     * close - shutdown and exit
+     */
+    public void close(CommandSession session) {
+        session.close();
+    }
+
+    /**
+     * exit - exit immediately (System.exit)
+     */
+
+    public void exit(int exitValue) {
+        exit(exitValue);
+    }
+
+    /**
+     * gc - perform a garbage collection
+     */
+    public long gc() {
+        Runtime.getRuntime().gc();
+        return Runtime.getRuntime().freeMemory();
+    }
+
+    /**
+     * init - uninstall all bundles
+     */
+
+    public void init() throws Exception {
+        Bundle bundles[] = getContext().getBundles();
+        for (Bundle b : bundles)
+            if (b.getBundleId() != 0)
+                b.uninstall();
+    }
+
+    /**
+     * setprop <key>=<value> - set the OSGi property
+     */
+    public void setprop(CommandSession session, String key, String value) {
+        session.put(key, value);
+    }
+
+    /**
+     * install - install and optionally start bundle from the given URL
+     * 
+     * @throws BundleException
+     */
+
+    public Bundle install(URL url) throws BundleException {
+        return getContext().installBundle(url.toExternalForm());
+    }
+
+    /**
+     * uninstall - uninstall the specified bundle(s)
+     * 
+     * @throws BundleException
+     */
+    public void uninstall(Bundle[] bundles) throws BundleException {
+        for (Bundle b : bundles) {
+            b.uninstall();
+        }
+    }
+
+    /**
+     * start - start the specified bundle(s)
+     */
+    public void start(Bundle[] bundles) throws BundleException {
+        for (Bundle b : bundles) {
+            b.start();
+        }
+    }
+
+    /**
+     * stop - stop the specified bundle(s)
+     */
+    public void stop(Bundle[] bundles) throws BundleException {
+        for (Bundle b : bundles) {
+            b.stop();
+        }
+    }
+
+    /**
+     * refresh - refresh the packages of the specified bundles
+     */
+    public void refresh(Bundle[] bundles) throws Exception {
+        if (pka != null)
+            pka.refreshPackages(bundles);
+        else
+            throw new RuntimeException("No PackageAdmin service registered");
+    }
+
+    /**
+     * update - update the specified bundle(s)
+     */
+    public void update(Bundle[] bundles) throws BundleException {
+        for (Bundle b : bundles) {
+            b.update();
+        }
+    }
+
+    /**
+     * status - display installed bundles and registered services
+     */
+    public List<Object> status() throws Exception {
+        List<Object> status = new ArrayList<Object>();
+        status.addAll(Arrays.asList(getContext().getBundles()));
+        status.addAll(Arrays.asList(getContext().getServiceReferences(null,
+                null)));
+        return status;
+    }
+
+    /**
+     * ss - display installed bundles (short status)
+     */
+    public Bundle[] ss() {
+        return getContext().getBundles();
+    }
+
+    /**
+     * services {filter} - display registered service details
+     */
+    public ServiceReference[] services(String filter) throws Exception {
+        return getContext().getServiceReferences(null, filter);
+    }
+
+    /**
+     * packages {<pkgname>|<id>|<location>} - display imported/exported
+     * package details
+     */
+    public ExportedPackage[] packages(Bundle bundle) throws Exception {
+        if (pka != null)
+            return pka.getExportedPackages(bundle);
+        else
+            throw new RuntimeException("No PackageAdmin service registered");
+    }
+
+    public ExportedPackage[] packages(String packageName) throws Exception {
+        if (pka != null)
+            return pka.getExportedPackages(packageName);
+        return null;
+    }
+
+    /**
+     * bundles - display details for all installed bundles
+     */
+    public Bundle[] bundles() {
+        return ss();
+    }
+
+    /**
+     * bundle (<id>|<location>) - display details for the specified bundle(s)
+     */
+
+    /**
+     * headers (<id>|<location>) - print bundle headers
+     */
+
+    @SuppressWarnings("unchecked")
+    public Dictionary headers(Bundle b, String locale) {
+        return b.getHeaders(locale);
+    }
+
+    /**
+     * log (<id>|<location>) - display log entries
+     */
+
+    @SuppressWarnings("unchecked")
+    public Collection<LogEntry> log(Bundle bundle) throws Exception {
+        if (lrs != null)
+            return Collections.list((Enumeration<LogEntry>) lrs.getLog());
+        else
+            throw new RuntimeException("LogReader not available");
+    }
+
+    /**
+     * exec <command> - execute a command in a separate process and wait
+     * 
+     * @throws IOException
+     */
+
+    public int exec(Object[] args, boolean fork) throws IOException {
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+        for (Object arg : args) {
+            sb.append(del);
+            sb.append(arg);
+            del = " ";
+        }
+        Process p = Runtime.getRuntime().exec(sb.toString());
+        if (fork) {
+            int c;
+            while ((c = p.getInputStream().read()) > 0)
+                System.out.print(c);
+        }
+        return p.exitValue();
+    }
+
+    /**
+     * fork <command> - execute a command in a separate process
+     */
+
+    public void fork(Object args[]) throws Exception {
+        exec(args, true);
+    }
+
+    /**
+     * sl {(<id>|<location>)} - display the start level for the specified
+     * bundle, or for the framework if no bundle specified
+     */
+    public int sl(Bundle b) throws Exception {
+        if (sls == null)
+            throw new RuntimeException("No StartLevel service registered");
+        if (b == null)
+            return sls.getStartLevel();
+        else
+            return sls.getBundleStartLevel(b);
+    }
+
+    /**
+     * setfwsl <start level> - set the framework start level
+     */
+    public int setfwsl(int n) throws Exception {
+        if (sls == null)
+            throw new RuntimeException("No StartLevel service registered");
+        int old = sls.getStartLevel();
+        sls.setStartLevel(n);
+        return old;
+    }
+
+    /**
+     * setbsl <start level> (<id>|<location>) - set the start level for the
+     * bundle(s)
+     */
+    public int setbsl(Bundle b, int n) throws Exception {
+        if (sls == null)
+            throw new RuntimeException("No StartLevel service registered");
+        int old = sls.getBundleStartLevel(b);
+        sls.setBundleStartLevel(b, n);
+        return old;
+    }
+
+    /**
+     * setibsl <start level> - set the initial bundle start level
+     */
+    public int setibsl(int n) throws Exception {
+        if (sls == null)
+            throw new RuntimeException("No StartLevel service registered");
+        int old = sls.getInitialBundleStartLevel();
+        sls.setInitialBundleStartLevel(n);
+        return old;
+    }
+
+    public Object convert(Class<?> desiredType, Object in) throws Exception {
+        return null;
+    }
+
+    String getLevel(int index) {
+        switch (index) {
+        case LogService.LOG_DEBUG:
+            return "DEBUG";
+        case LogService.LOG_INFO:
+            return "INFO ";
+        case LogService.LOG_WARNING:
+            return "WARNI";
+        case LogService.LOG_ERROR:
+            return "ERROR";
+        default:
+            return "<" + index + ">";
+        }
+    }
+
+    public CharSequence format(Object target, int level, Converter escape) {
+        if (target instanceof LogEntry) {
+            LogEntry entry = (LogEntry) target;
+            switch (level) {
+            case LINE:
+                Formatter f = new Formatter();
+                f.format("%tT %04d %s %s", entry.getTime(), entry.getBundle()
+                        .getBundleId(), getLevel(entry.getLevel())+"", entry
+                        .getMessage()+"");
+                return f.toString();
+                
+            case PART:
+                Formatter f2 = new Formatter();
+                f2.format("%tT %s", entry.getTime(), entry
+                        .getMessage());
+                return f2.toString();
+            }
+        }
+        return null;
+    }
+    /**
+     * profilelog - Display & flush the profile log messages
+     */
+
+}
diff --git a/gogo/src/aQute/shell/lang/Support.java b/gogo/src/aQute/shell/lang/Support.java
new file mode 100644
index 0000000..bdf27de
--- /dev/null
+++ b/gogo/src/aQute/shell/lang/Support.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package aQute.shell.lang;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+
+
+public class Support implements Converter {
+
+    public Object convert(Class<?> desiredType, final Object in) throws Exception {
+        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;
+    }
+
+    public CharSequence format(Object target, int level, Converter escape)
+            throws Exception {
+        return null;
+    }
+}
diff --git a/gogo/src/aQute/shell/osgi/OSGiCommands.java b/gogo/src/aQute/shell/osgi/OSGiCommands.java
new file mode 100644
index 0000000..f715a89
--- /dev/null
+++ b/gogo/src/aQute/shell/osgi/OSGiCommands.java
@@ -0,0 +1,302 @@
+/*
+ * 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 aQute.shell.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.command.*;
+
+public class OSGiCommands implements Converter {
+	Bundle	bundle;
+	String	COLUMN	= "%40s %s\n";
+
+	protected OSGiCommands(Bundle bundle) {
+		this.bundle = bundle;
+	}
+
+//	Bundle[] getBundles() {
+//		return getContext().getBundles();
+//	}
+
+	public BundleContext getContext() {
+		if ( bundle.getState() != Bundle.ACTIVE )
+			throw new IllegalStateException("Framework is not started yet");
+		return bundle.getBundleContext();
+	}
+	
+	CharSequence print(Bundle bundle) {
+	    String version = (String) bundle.getHeaders().get("Bundle-Version");
+	    if ( version == null )
+	        version = "0.0.0";
+		return String.format("%06d %s %s-%s", bundle.getBundleId(),
+				getState(bundle), bundle.getSymbolicName(), version);
+	}
+
+	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;
+	}
+
+	CharSequence getShortNames(String[] list) {
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (String s : list) {
+			sb.append(del + getShortName(s));
+			del = " | ";
+		}
+		return sb;
+	}
+
+	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 "ACT";
+
+		case Bundle.INSTALLED:
+			return "INS";
+
+		case Bundle.RESOLVED:
+			return "RES";
+
+		case Bundle.STARTING:
+			return "STA";
+
+		case Bundle.STOPPING:
+			return "STO";
+
+		case Bundle.UNINSTALLED:
+			return "UNI ";
+		}
+		return null;
+	}
+
+	public void grep(String match) throws IOException {
+		Pattern p = Pattern.compile(match);
+		BufferedReader rdr = new BufferedReader(
+				new InputStreamReader(System.in));
+		String s = rdr.readLine();
+		while (s != null) {
+			if (p.matcher(s).find()) {
+				System.out.println(s);
+			}
+			s = rdr.readLine();
+		}
+	}
+
+	public String tac() throws IOException {
+		StringWriter sw = new StringWriter();
+		BufferedReader rdr = new BufferedReader(
+				new InputStreamReader(System.in));
+		String s = rdr.readLine();
+		while (s != null) {
+			sw.write(s);
+			s = rdr.readLine();
+		}
+		return sw.toString();
+	}
+
+	public CharSequence echo(CommandSession session, Object args[]) {
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (Object arg : args) {
+			sb.append(del);
+			if (arg != null) {
+				sb.append(arg);
+				del = " ";
+			}
+		}
+		return sb;
+	}
+
+	public void each(CommandSession session, Collection<Object> list, Function closure) throws Exception {
+		List<Object> args = new ArrayList<Object>();
+		args.add(null);
+		for (Object x : list) {
+			args.set(0, x);
+			Object result = closure.execute(session, args);
+			System.out.println(session.format(result,Converter.INSPECT));
+		}
+	}
+
+	public Bundle bundle(Bundle i) {
+		return i;
+	}
+
+	public String[] ls(CommandSession session, File f) throws Exception{
+		File cwd = (File) session.get("_cwd");
+		if (cwd == null)
+			cwd = new File("").getAbsoluteFile();
+		
+		if (  f == null )
+			f = cwd;
+		else if (!f.isAbsolute())
+			f = new File(cwd, f.getPath());
+
+		if ( f.isDirectory() )
+			return f.list();
+
+		if ( f.isFile() ) {
+			cat(session,f);
+		}
+		
+		return null;
+	}
+
+	public Object cat(CommandSession session, File f ) throws Exception {
+		File cwd = (File) session.get("_cwd");
+		if (cwd == null)
+			cwd = new File("").getAbsoluteFile();
+		
+		if ( !f.isAbsolute() )
+			f = new File(cwd,f.getPath());
+		
+		ByteArrayOutputStream bout = new ByteArrayOutputStream();
+		FileInputStream in = new FileInputStream(f);
+		byte [] buffer = new byte[ (int) (f.length() % 100000) ];
+		int size = in.read(buffer);
+		while ( size > 0 ) {
+			bout.write(buffer,0,size);
+			size = in.read(buffer);
+		}
+		return new String(bout.toByteArray());
+	}
+	public Object convert(Class<?> desiredType, Object in) throws Exception {
+		if (desiredType == Bundle.class)
+			return convertBundle(in);
+        else if (desiredType == ServiceReference.class)
+            return convertServiceReference(in);
+        else if (desiredType == Class.class)
+            return Class.forName(in.toString());
+        else if (desiredType.isAssignableFrom(String.class) && in instanceof InputStream)
+            return read(((InputStream) in));
+
+		return null;
+	}
+
+	private Object convertServiceReference(Object in)
+			throws InvalidSyntaxException {
+		String s = in.toString();
+		if (s.startsWith("(") && s.endsWith(")")) {
+			ServiceReference refs[] = getContext().getServiceReferences(null, String
+					.format("(|(service.id=%s)(service.pid=%s))", in, in));
+			if (refs != null && refs.length > 0)
+				return refs[0];
+		}
+
+		ServiceReference refs[] = getContext().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 getContext().getBundle(id);
+		} catch (NumberFormatException nfe) {
+			// Ignore
+		}
+
+		Bundle bundles[] = getContext().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;
+	}	
+
+	public 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;
+    }
+
+    public void start(Bundle b) throws BundleException {
+		b.start();
+	}
+	
+	public void stop(Bundle b) throws BundleException {
+		b.stop();
+	}
+	
+	public Object service(String clazz, String filter) throws InvalidSyntaxException {
+		ServiceReference ref[] = getContext().getServiceReferences(clazz,filter);
+		if (ref == null )
+			return null;
+		
+		return getContext().getService(ref[0]);
+	}
+	
+}
diff --git a/gogo/src/aQute/shell/osgi/OSGiShell.java b/gogo/src/aQute/shell/osgi/OSGiShell.java
new file mode 100644
index 0000000..3b35496
--- /dev/null
+++ b/gogo/src/aQute/shell/osgi/OSGiShell.java
@@ -0,0 +1,111 @@
+/*
+ * 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 aQute.shell.osgi;
+
+import org.osgi.framework.*;
+import org.osgi.service.command.*;
+import org.osgi.service.component.*;
+import org.osgi.service.packageadmin.*;
+import org.osgi.service.permissionadmin.*;
+import org.osgi.service.startlevel.*;
+import org.osgi.service.threadio.*;
+
+import aQute.shell.runtime.*;
+
+public class OSGiShell extends CommandShellImpl {
+    Bundle       bundle;
+    OSGiCommands commands;
+
+    protected void activate(ComponentContext context) throws Exception {
+        this.bundle = context.getBundleContext().getBundle();
+        if (threadIO == null)
+            threadIO = (ThreadIO) context.locateService("x");
+        start();
+    }
+
+    public void start() throws Exception {
+        commands = new OSGiCommands(bundle);
+        addCommand("osgi", this.bundle);
+        addCommand("osgi", commands);
+        setConverter(commands);
+        if (bundle.getState() == Bundle.ACTIVE) {
+            addCommand("osgi", commands.service(StartLevel.class.getName(),
+                    null), StartLevel.class);
+            addCommand("osgi", commands.service(PackageAdmin.class.getName(),
+                    null), PackageAdmin.class);
+            addCommand("osgi", commands.service(
+                    PermissionAdmin.class.getName(), null),
+                    PermissionAdmin.class);
+            addCommand("osgi", commands.getContext(), BundleContext.class);
+        }
+    }
+
+    protected void deactivate(ComponentContext context) {
+        System.out.println("Deactivating");
+    }
+
+    public Object get(String name) {
+        if (bundle.getBundleContext() != null) {
+            BundleContext context = bundle.getBundleContext();
+            try {
+                Object cmd = super.get(name);
+                if (cmd != null)
+                    return cmd;
+
+                int n = name.indexOf(':');
+                if (n < 0)
+                    return null;
+
+                String service = name.substring(0, n);
+                String function = name.substring(n + 1);
+
+                String filter = String.format(
+                        "(&(osgi.command.scope=%s)(osgi.command.function=%s))",
+                        service, function);
+                ServiceReference refs[] = context.getServiceReferences(null,
+                        filter);
+                if (refs == null || refs.length == 0)
+                    return null;
+
+                if (refs.length > 1)
+                    throw new IllegalArgumentException(
+                            "Command name is not unambiguous: " + name
+                                    + ", found multiple impls");
+
+                return new ServiceCommand(this, refs[0], function);
+            } catch (InvalidSyntaxException ise) {
+                ise.printStackTrace();
+            }
+        }
+        return super.get(name);
+    }
+
+    public void setThreadio(Object t) {
+        super.setThreadio((ThreadIO) t);
+    }
+
+    public void setBundle(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    public void setConverter(Converter c) {
+        super.setConverter(c);
+    }
+
+}
diff --git a/gogo/src/aQute/shell/osgi/ServiceCommand.java b/gogo/src/aQute/shell/osgi/ServiceCommand.java
new file mode 100644
index 0000000..61d4087
--- /dev/null
+++ b/gogo/src/aQute/shell/osgi/ServiceCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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 aQute.shell.osgi;
+
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.command.*;
+
+import aQute.shell.runtime.*;
+
+public class ServiceCommand extends Reflective implements Function {
+	ServiceReference	ref;
+	OSGiShell			shell;
+	String				name;
+	
+	public ServiceCommand(OSGiShell shell, ServiceReference ref, String name) {
+		this.shell =shell;
+		this.ref = ref;
+		this.name = name;
+	}
+
+	public Object execute(CommandSession session, List<Object> arguments) throws Exception {
+		try {
+			Object target = shell.bundle.getBundleContext().getService(ref);
+			Object result = method(session,target, name, arguments);
+			if ( result != CommandShellImpl.NO_SUCH_COMMAND )
+				return result;
+			
+			throw new IllegalArgumentException("Service does not implement promised command " + ref + " " + name );
+		} finally {
+			shell.bundle.getBundleContext().ungetService(ref);
+		}
+	}
+}
diff --git a/gogo/src/aQute/shell/runtime/Closure.java b/gogo/src/aQute/shell/runtime/Closure.java
new file mode 100644
index 0000000..00a297b
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/Closure.java
@@ -0,0 +1,233 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+public class Closure extends Reflective implements Function {
+    private static final long serialVersionUID = 1L;
+    final CharSequence        source;
+    final Closure             parent;
+    CommandSessionImpl        session;
+    List<Object>              parms;
+
+    Closure(CommandSessionImpl session, Closure parent, CharSequence source) {
+        this.session = session;
+        this.parent = parent;
+        this.source = source;
+    }
+
+    public Object execute(CommandSession x, List<Object> values)
+            throws Exception {
+        parms = values;
+        Parser parser = new Parser(source);
+        ArrayList<Pipe> pipes = new ArrayList<Pipe>();
+        List<List<List<CharSequence>>> program = parser.program();
+
+        for (List<List<CharSequence>> statements : program) {
+            Pipe current = new Pipe(this, statements);
+
+            if (pipes.isEmpty()) {
+                current.setIn(session.in);
+                current.setOut(session.out);
+            } else {
+                Pipe previous = pipes.get(pipes.size() - 1);
+                previous.connect(current);
+            }
+            pipes.add(current);
+        }
+        if (pipes.size() == 0)
+            return null;
+
+        if (pipes.size() == 1) {
+            pipes.get(0).run();
+        } else {
+            for (Pipe pipe : pipes) {
+                pipe.start();
+            }
+            for (Pipe pipe : pipes) {
+                pipe.join();
+            }
+        }
+
+        Pipe last = pipes.get(pipes.size() - 1);
+        if (last.exception != null)
+            throw last.exception;
+
+        if (last.result instanceof Object[]) {
+            return Arrays.asList((Object[]) last.result);
+        }
+        return last.result;
+    }
+
+    Object executeStatement(List<CharSequence> statement) throws Exception {
+        Object result;
+        List<Object> values = new ArrayList<Object>();
+        Object cmd = eval(statement.remove(0));
+        for (CharSequence token : statement)
+            values.add(eval(token));
+
+        result = execute(cmd, values);
+        return result;
+    }
+
+    private Object execute(Object cmd, List<Object> values) throws Exception {
+        if (cmd == null) {
+            if (values.isEmpty())
+                return null;
+            else
+                throw new IllegalArgumentException(
+                        "Command name evaluates to null");
+        }
+
+        // Now there are the following cases
+        // <string> '=' statement // complex assignment
+        // <string> statement // cmd call
+        // <object> // value of <object>
+        // <object> statement // method call
+
+        if (cmd instanceof CharSequence) {
+            String scmd = cmd.toString();
+
+            if (values.size() > 0 && "=".equals(values.get(0))) {
+                if (values.size() == 0)
+                    return session.variables.remove(scmd);
+                else {
+                    Object value = execute(values.get(1), values.subList(2,
+                            values.size()));
+                    return assignment(scmd, value);
+                }
+            } else {
+                String scopedFunction = scmd;
+                Object x = get(scmd);
+                if ( !(x instanceof Function) ) {
+                    if (scmd.indexOf(':') < 0) {
+                        scopedFunction = "*:" + scmd;
+                    }
+                    x = get(scopedFunction);
+                    if (x == null || !(x instanceof Function)) {
+                        if (values.isEmpty())
+                            return scmd;
+                        throw new IllegalArgumentException("Command not found:  "
+                                + scopedFunction);
+                    } 
+                 }
+                return ((Function) x).execute(session, values);
+            }
+        } else {
+            if (values.isEmpty())
+                return cmd;
+            else
+                return method(session, cmd, values.remove(0).toString(), values);
+        }
+    }
+
+    private Object assignment(Object name, Object value) {
+        session.variables.put(name, value);
+        return value;
+    }
+
+    private Object eval(CharSequence seq) throws Exception {
+        int end = seq.length();
+        switch (seq.charAt(0)) {
+        case '$':
+            return var(seq);
+        case '<':
+            Closure c = new Closure(session, this, seq.subSequence(1, end - 1));
+            return c.execute(session, parms);
+        case '[':
+            return array(seq.subSequence(1, end - 1));
+
+        case '{':
+            return new Closure(session, this, seq.subSequence(1, end - 1));
+
+        default:
+            String result = new Parser(seq).unescape();
+            if ("null".equals(result))
+                return null;
+            if ("true".equalsIgnoreCase(result))
+                return true;
+            if ("false".equalsIgnoreCase(result))
+                return false;
+            return seq;
+        }
+    }
+
+    private Object array(CharSequence array) throws Exception {
+        List<Object> list = new ArrayList<Object>();
+        Map<Object, Object> map = new LinkedHashMap<Object, Object>();
+        Parser p = new Parser(array);
+
+        while (!p.eof()) {
+            CharSequence token = p.value();
+
+            p.ws();
+            if (p.peek() == '=') {
+                p.next();
+                p.ws();
+                if (!p.eof()) {
+                    CharSequence value = p.messy();
+                    map.put(eval(token), eval(value));
+                }
+            } else
+                list.add(eval(token));
+
+            if (p.peek() == ',')
+                p.next();
+            p.ws();
+        }
+        p.ws();
+        if (!p.eof())
+            throw new IllegalArgumentException("Invalid array syntax: " + array);
+
+        if (map.size() != 0 && list.size() != 0)
+            throw new IllegalArgumentException(
+                    "You can not mix maps and arrays: " + array);
+
+        if (map.size() > 0)
+            return map;
+        else
+            return list;
+    }
+
+    private Object var(CharSequence var) throws Exception {
+        String name = eval(var.subSequence(1, var.length())).toString();
+        return get(name);
+    }
+
+    /**
+     * 
+     * @param name
+     * @return
+     */
+    private Object get(String name) {
+        if (parms != null) {
+            if ("it".equals(name))
+                return parms.get(0);
+            if ("args".equals(name))
+                return parms;
+
+            if (name.length() == 1 && Character.isDigit(name.charAt(0)))
+                return parms.get(name.charAt(0) - '0');
+        }
+        return session.get(name);
+    }
+}
diff --git a/gogo/src/aQute/shell/runtime/Command.java b/gogo/src/aQute/shell/runtime/Command.java
new file mode 100644
index 0000000..cd9f500
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/Command.java
@@ -0,0 +1,38 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+public class Command extends Reflective implements Function {
+	Object target;
+	String function;
+
+	public Command(Object target, String function) {
+		this.function = function;
+		this.target = target;
+	}
+
+	public Object execute(CommandSession session, List<Object> arguments) throws Exception {
+		return method(session,target, function, arguments);
+	}
+
+}
diff --git a/gogo/src/aQute/shell/runtime/CommandSessionImpl.java b/gogo/src/aQute/shell/runtime/CommandSessionImpl.java
new file mode 100644
index 0000000..2607554
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/CommandSessionImpl.java
@@ -0,0 +1,215 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+public class CommandSessionImpl implements CommandSession, Converter {
+	String						COLUMN			= "%-20s %s\n";
+	InputStream in;
+	PrintStream out;
+	PrintStream err;
+	CommandShellImpl service;
+	Map<Object, Object> variables = new HashMap<Object, Object>();
+
+	CommandSessionImpl(CommandShellImpl service, InputStream in,
+			PrintStream out, PrintStream err) {
+		this.service = service;
+		this.in = in;
+		this.out = out;
+		this.err = err;
+	}
+
+	public void close() {
+	}
+
+	public Object execute(CharSequence commandline) throws Exception {
+		assert service != null;
+		assert service.threadIO != null;
+		
+		Closure impl = new Closure(this, null, commandline);
+		Object result = impl.execute(this, null);
+		return result;
+	}
+
+	public InputStream getKeybord() {
+		return in;
+	}
+
+	public Object get(String name) {
+		if (variables != null && variables.containsKey(name))
+			return variables.get(name);
+
+		return service.get(name);
+	}
+
+	public void put(String name, Object value) {
+		variables.put(name, value);
+	}
+
+	public PrintStream getConsole() {
+		return out;
+	}
+	
+	
+	@SuppressWarnings("unchecked")
+	public
+	CharSequence format(Object target, int level, Converter escape ) throws Exception {
+		if (target == null)
+			return "null";
+
+		if (target instanceof CharSequence )
+			return (CharSequence) target;
+		
+		for (Converter c : service.converters) {
+			CharSequence s = c.format(target, level, this);
+			if (s != null)
+				return s;
+		}
+
+		if (target.getClass().isArray()) {
+			if ( target.getClass().getComponentType().isPrimitive()) {
+				if ( target.getClass().getComponentType() == boolean.class ) 
+					return Arrays.toString((boolean[]) target);
+				else if ( target.getClass().getComponentType() == byte.class ) 
+					return Arrays.toString((byte[]) target);
+				else if ( target.getClass().getComponentType() == short.class ) 
+					return Arrays.toString((short[]) target);
+				else if ( target.getClass().getComponentType() == int.class ) 
+					return Arrays.toString((int[]) target);
+				else if ( target.getClass().getComponentType() == long.class ) 
+					return Arrays.toString((long[]) target);
+				else if ( target.getClass().getComponentType() == float.class ) 
+					return Arrays.toString((float[]) target);
+				else if ( target.getClass().getComponentType() == double.class ) 
+					return Arrays.toString((double[]) target);
+				else if ( target.getClass().getComponentType() == char.class ) 
+					return Arrays.toString((char[]) target);
+			}
+			target = Arrays.asList((Object[]) target);
+		}
+		if (target instanceof Collection) {
+			if (level == Converter.INSPECT) {
+				StringBuilder sb = new StringBuilder();
+				Collection<?> c = (Collection<?>) target;
+				for (Object o : c) {
+					sb.append(format(o, level + 1, this));
+					sb.append("\n");
+				}
+				return sb;
+			} else if (level == Converter.LINE) {
+				StringBuilder sb = new StringBuilder();
+				String del = "[";
+				Collection<?> c = (Collection<?>) target;
+				for (Object o : c) {
+					sb.append(del);
+					sb.append(format(o, level + 1, this));
+					del = ", ";
+				}
+				sb.append("]");
+				return sb;
+			}
+		}
+		if ( target instanceof Dictionary ) {
+			Map<Object,Object> result = new HashMap<Object,Object>();
+			for ( Enumeration e = ((Dictionary)target).keys(); e.hasMoreElements(); ) {
+				Object key = e.nextElement();
+				result.put(key, ((Dictionary)target).get(key));
+			}
+			target = result;
+		}
+		if (target instanceof Map) {
+			if (level == Converter.INSPECT) {
+				StringBuilder sb = new StringBuilder();
+				Map<?,?> c = (Map<?,?>) target;
+				for (Map.Entry<?,?> entry : c.entrySet()) {
+					CharSequence key = format(entry.getKey(), level + 1, this);
+					sb.append(key);
+					for ( int i=key.length(); i<20; i++ )
+						sb.append(' ');
+					sb.append(format(entry.getValue(), level + 1, this));
+					sb.append("\n");
+				}
+				return sb;
+			} else if (level == Converter.LINE) {
+				StringBuilder sb = new StringBuilder();
+				String del = "[";
+				Map<?,?> c = (Map<?,?>) target;
+				for (Map.Entry<?,?> entry : c.entrySet()) {
+					sb.append(del);
+					sb.append(format(entry, level + 1,this));
+					del = ", ";
+				}
+				sb.append("]");
+				return sb;
+			}
+		}
+		if (level == Converter.INSPECT)
+			return inspect(target);
+		else
+			return target.toString();
+	}
+
+	CharSequence inspect(Object b) {
+		boolean found = false;
+		Formatter f = new Formatter();
+		Method methods[] = b.getClass().getMethods();
+		for (Method m : methods) {
+			try {
+				String name = m.getName();
+				if (m.getName().startsWith("get")
+						&& !m.getName().equals("getClass")
+						&& m.getParameterTypes().length == 0
+						&& Modifier.isPublic(m.getModifiers())) {
+					found = true;
+					name = name.substring(3);
+					m.setAccessible(true);
+					Object value = m.invoke(b, (Object[]) null);
+					f.format(COLUMN, name, format(value, Converter.LINE, this));
+				}
+			} catch (IllegalAccessException e) {
+				// Ignore
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		if (found)
+			return (StringBuilder) f.out();
+		else
+			return b.toString();
+	}
+
+
+	public Object convert(Class<?> desiredType, Object in)  {
+		return service.convert(desiredType, in);
+	}
+
+	public CharSequence format(Object result, int inspect) {
+	    try {
+		return format(result,inspect,this);
+	    } catch(Exception e ) {
+	        return "<can not format " + result + ":" + e;
+	    }
+	}
+
+}
diff --git a/gogo/src/aQute/shell/runtime/CommandShellImpl.java b/gogo/src/aQute/shell/runtime/CommandShellImpl.java
new file mode 100644
index 0000000..5326343
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/CommandShellImpl.java
@@ -0,0 +1,140 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+import org.osgi.service.threadio.*;
+
+public class CommandShellImpl implements CommandProcessor {
+    Set<Converter>             converters      = new HashSet<Converter>();
+    protected ThreadIO         threadIO;
+    public final static Object NO_SUCH_COMMAND = new Object();
+    Map<String, Object>        commands        = new LinkedHashMap<String, Object>();
+
+    public CommandShellImpl() {
+        addCommand("shell", this, "addCommand" );
+    }
+
+    public CommandSession createSession(InputStream in, PrintStream out,
+            PrintStream err) {
+
+        return new CommandSessionImpl(this, in, out, err);
+    }
+
+    public void setThreadio(ThreadIO threadIO) {
+        this.threadIO = threadIO;
+    }
+
+    public void setConverter(Converter c) {
+        converters.add(c);
+    }
+
+    public void unsetConverter(Converter c) {
+        converters.remove(c);
+    }
+
+    public Object get(String name) {
+        name = name.toLowerCase();
+        int n = name.indexOf(':');
+        if (n < 0)
+            return null;
+
+        String function = name.substring(n);
+
+        Object cmd = null;
+
+        if (commands.containsKey(name)) {
+            cmd = commands.get(name);
+        } else {
+            String scope = name.substring(0, n);
+            if (scope.equals("*")) {
+                for (Map.Entry<String, Object> entry : commands.entrySet()) {
+                    if (entry.getKey().endsWith(function)) {
+                        cmd = entry.getValue();
+                        break;
+                    }
+                }
+            }
+        }
+        if (cmd == null)
+            return null;
+
+        if (cmd instanceof Function)
+            return cmd;
+        else
+            return new Command(cmd, function.substring(1));
+    }
+
+    public void addCommand(String scope, Object target) {
+        addCommand(scope,target,target.getClass());
+    }
+
+    public void addCommand(String scope, Object target, Class<?> functions) {
+        if (target == null)
+            return;
+
+        String[] names = getFunctions(functions);
+        for (String function : names) {
+            addCommand(scope, target, function);
+        }
+    }
+
+    public void addCommand(String scope, Object target, String function) {
+        commands.put((scope + ":" + function).toLowerCase(), target);
+    }
+
+    public String[] getFunctions(Class<?> target) {
+        String[] functions;
+        Set<String> list = new TreeSet<String>();
+        Method methods[] = target.getMethods();
+        for (Method m : methods) {
+            list.add(m.getName());
+            if (m.getName().startsWith("get")) {
+                String s = m.getName().substring(3);
+                if (s.length() > 0)
+                    list.add(s.substring(0, 1).toLowerCase() + s.substring(1));
+            }
+        }
+        functions = list.toArray(new String[list.size()]);
+        return functions;
+    }
+
+    protected void put(String name, Object target) {
+        commands.put(name, target);
+    }
+
+    public Object convert(Class<?> desiredType, Object in) {
+        for ( Converter c : converters ) {
+            try {
+            Object converted = c.convert(desiredType, in);
+            if ( converted != null)
+                return converted;
+            } catch( Exception e ) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/gogo/src/aQute/shell/runtime/Parser.java b/gogo/src/aQute/shell/runtime/Parser.java
new file mode 100644
index 0000000..8585847
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/Parser.java
@@ -0,0 +1,280 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.util.*;
+
+public class Parser {
+	int					current	= 0;
+	CharSequence		text;
+	boolean				escaped;
+	static final String	SPECIAL	= "<;|{[\"'$'`(=";
+
+	public Parser(CharSequence program) {
+		text = program;
+	}
+
+	void ws() {
+		while (!eof() && Character.isWhitespace(peek())) {
+			current++;
+			if (peek() == '/' && current < text.length()-2 && text.charAt(current + 1) == '/') {
+				comment();
+			}
+		}
+	}
+
+	private void comment() {
+		while (!eof() && peek() != '\n' && peek() != '\r')
+			next();
+	}
+
+	boolean eof() {
+		return current >= text.length();
+	}
+
+	char peek() {
+		escaped = false;
+		if (eof())
+			return 0;
+
+		char c = text.charAt(current);
+
+		if (c == '\\') {
+			escaped = true;
+			c = text.charAt(++current);
+
+			switch (c) {
+			case 't':
+				c = '\t';
+				break;
+			case '\r':
+			case '\n':
+				c = ' ';
+				break;
+			case 'b':
+				c = '\b';
+				break;
+			case 'f':
+				c = '\f';
+				break;
+			case 'n':
+				c = '\n';
+				break;
+			case 'r':
+				c = '\r';
+				break;
+			case 'u':
+				c = unicode();
+				break;
+			default:
+				// We just take the next character literally
+				// but have the escaped flag set, important for {},[] etc
+			}
+		}
+		return c;
+	}
+
+	public List<List<List<CharSequence>>> program() {
+		List<List<List<CharSequence>>> program = new ArrayList<List<List<CharSequence>>>();
+		ws();
+		if (!eof()) {
+			program.add(statements());
+			while (peek() == '|') {
+				current++;
+				program.add(statements());
+			}
+		}
+		if (!eof())
+			throw new RuntimeException("Program has trailing text: "
+					+ context(current));
+
+		return program;
+	}
+
+	CharSequence context(int around) {
+		return text.subSequence(Math.max(0, current - 20), Math.min(text
+				.length(), current + 4));
+	}
+
+	public List<List<CharSequence>> statements() {
+		List<List<CharSequence>> statements = new ArrayList<List<CharSequence>>();
+		statements.add(statement());
+		while (peek() == ';') {
+			current++;
+			statements.add(statement());
+		}
+		return statements;
+	}
+
+	public List<CharSequence> statement() {
+		List<CharSequence> statement = new ArrayList<CharSequence>();
+		statement.add(value());
+		while (!eof()) {
+			ws();
+			if (peek() == '|' || peek() == ';')
+				break;
+
+			if (!eof())
+				statement.add(messy());
+		}
+		return statement;
+	}
+
+	public CharSequence messy() {
+		char c = peek();
+		if (c > 0 && SPECIAL.indexOf(c)< 0) {
+			int start = current++;
+			while (!eof()) {
+				c = peek();
+				if (c == ';' || c == '|' || Character.isWhitespace(c))
+					break;
+				next();
+			}
+
+			return text.subSequence(start, current);
+		} else
+			return value();
+	}
+
+	CharSequence value() {
+		ws();
+
+		int start = current;
+		char c = next();
+		switch (c) {
+		case '{':
+			return text.subSequence(start, find('}', '{'));
+		case '(':
+			return text.subSequence(start, find(')', '('));
+		case '[':
+			return text.subSequence(start, find(']', '['));
+		case '"':
+			return text.subSequence(start + 1, quote('"'));
+		case '\'':
+			return text.subSequence(start + 1, quote('\''));
+		case '<':
+			return text.subSequence(start, find('>', '<'));
+		case '$':
+			value();
+			return text.subSequence(start, current);
+		}
+
+		if (Character.isJavaIdentifierPart(c)) {
+			// Some identifier or number
+			while (!eof()) {
+				c = peek();
+				if (c!=':' && !Character.isJavaIdentifierPart(c) && c != '.')
+					break;
+				next();
+			}
+		} else {
+			// Operator, repeat while in operator class
+			while (!eof()) {
+				c = peek();
+				if (Character.isWhitespace(c)
+						|| Character.isJavaIdentifierPart(c))
+					break;
+			}
+		}
+		return text.subSequence(start, current);
+	}
+
+	char next() {
+		char c = peek();
+		current++;
+		return c;
+	}
+
+	char unicode() {
+		if (current + 4 > text.length())
+			throw new IllegalArgumentException(
+					"Unicode \\u escape at eof at pos ..." + context(current)
+							+ "...");
+
+		String s = text.subSequence(current, current + 4).toString();
+		int n = Integer.parseInt(s, 16);
+		return (char) n;
+	}
+
+	private int find(char target, char deeper) {
+		int start = current;
+		int level = 1;
+
+		while (level != 0) {
+			if (eof())
+				throw new RuntimeException(
+						"Eof found in the middle of a compound for '" + target
+								+ deeper + "', begins at " + context(start));
+
+			char c = next();
+			if (!escaped) {
+				if (c == target)
+					level--;
+				else if (c == deeper)
+					level++;
+				else if (c == '"')
+					quote('"');
+				else if (c == '\'')
+					quote('\'');
+				else if (c == '`')
+					quote('`');
+			}
+		}
+		return current;
+	}
+
+	int quote(char which) {
+		while (!eof() && (peek() != which || escaped))
+			next();
+
+		return current++;
+	}
+
+	CharSequence findVar() {
+		int start = current - 1;
+		char c = peek();
+
+		if (c == '{') {
+			next();
+			int end = find('}', '{');
+			return text.subSequence(start, end);
+		}
+
+		if (Character.isJavaIdentifierStart(c)) {
+			while (!eof() && Character.isJavaIdentifierPart(c) || c == '.') {
+				next();
+			}
+			return text.subSequence(start, current);
+		}
+		throw new IllegalArgumentException(
+				"Reference to variable does not match syntax of a variable: "
+						+ context(start));
+	}
+
+	public String toString() {
+		return "..." + context(current) + "...";
+	}
+
+	public String unescape() {
+		StringBuilder sb = new StringBuilder();
+		while (!eof())
+			sb.append(next());
+		return sb.toString();
+	}
+}
diff --git a/gogo/src/aQute/shell/runtime/Pipe.java b/gogo/src/aQute/shell/runtime/Pipe.java
new file mode 100644
index 0000000..c6f04e8
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/Pipe.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package aQute.shell.runtime;
+
+import java.io.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+public class Pipe extends Thread {
+	InputStream in;
+	PrintStream out;
+	PipedOutputStream pout;
+	Closure closure;
+	Exception exception;
+	Object result;
+	List<List<CharSequence>> statements;
+
+	public Pipe(Closure closure, List<List<CharSequence>> statements) {
+		super("pipe-" + statements);
+		this.closure = closure;
+		this.statements = statements;
+	}
+
+	public void setIn(InputStream in) {
+		this.in = in;
+	}
+
+	public void setOut(PrintStream out) {
+		this.out = out;
+	}
+
+	public Pipe connect(Pipe next) throws IOException {
+		next.setOut(out);
+		pout = new PipedOutputStream();
+		next.setIn(new PipedInputStream(pout));
+		out = new PrintStream(pout);
+		return next;
+
+	}
+
+	public void run() {
+		closure.session.service.threadIO.setStreams(in, out, System.err);
+		try {
+			for (List<CharSequence> statement : statements) {
+				result = closure.executeStatement(statement);
+				if ( result != null && pout != null )
+					out.println(closure.session.format(result, Converter.INSPECT));
+			}
+		} catch (Exception e) {
+			exception = e;
+		} finally {
+			out.flush();
+			closure.session.service.threadIO.close();
+			try {
+				if ( in instanceof PipedInputStream )
+					in.close();
+				if (pout!=null)
+					pout.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/gogo/src/aQute/shell/runtime/Reflective.java b/gogo/src/aQute/shell/runtime/Reflective.java
new file mode 100644
index 0000000..284191b
--- /dev/null
+++ b/gogo/src/aQute/shell/runtime/Reflective.java
@@ -0,0 +1,207 @@
+/*
+ * 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 aQute.shell.runtime;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+
+public class Reflective {
+    public final static Object      NO_MATCH = new Object();
+    public 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" }));
+
+    public Object method(CommandSession session, Object target, String name,
+            List<Object> args) throws IllegalArgumentException,
+            IllegalAccessException, InvocationTargetException, Exception {
+        Method[] methods = target.getClass().getMethods();
+        name = name.toLowerCase();
+
+        String get = "get" + name;
+        String is = "is" + name;
+        String set = "set" + name;
+
+        if (KEYWORDS.contains(name))
+            name = "_" + name;
+
+        Method bestMethod = null;
+        Object[] bestArgs = null;
+        int match = -1;
+        for (Method m : methods) {
+            String mname = m.getName().toLowerCase();
+            if (mname.equals(name) || mname.equals(get) || mname.equals(set)
+                    || mname.equals(is)) {
+                Class<?>[] types = m.getParameterTypes();
+
+                // Check if the command takes a session
+                if (types.length > 0
+                        && CommandSession.class.isAssignableFrom(types[0])) {
+                    args.add(0, session);
+                }
+
+                Object[] parms = new Object[types.length];
+                // if (types.length >= args.size() ) {
+                int local = coerce(session, target, types, parms, args);
+                if (local == types.length || local > match) {
+                    bestMethod = m;
+                    bestArgs = parms;
+                    match = local;
+                }
+                // }
+                // if (match == -1 && types.length == 1
+                // && types[0] == Object[].class) {
+                // bestMethod = m;
+                // Object value = args.toArray();
+                // bestArgs = new Object[] { value };
+                // }
+            }
+        }
+
+        if (bestMethod != null) {
+            bestMethod.setAccessible(true);
+            return bestMethod.invoke(target, bestArgs);
+        } else
+            throw new IllegalArgumentException("Cannot find command:" + name
+                    + " with args:" + args);
+    }
+
+    /**
+     * Complex routein to convert the arguments given from the command line to
+     * the arguments of the method call. First, an attempt is made to convert
+     * each argument. If this fails, a check is made to see if varargs can be
+     * applied. This happens when the last method argument is an array.
+     * 
+     * @param session
+     * @param target
+     * @param types
+     * @param out
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    private int coerce(CommandSession session, Object target, Class<?> types[],
+            Object out[], List<Object> in) throws Exception {
+        int i = 0;
+        while (i < out.length) {
+            out[i] = null;
+            try {
+                // Try to convert one argument
+                out[i] = coerce(session, target, types[i], in.get(i));
+                if (out[i] == NO_MATCH) {
+                    // Failed
+                    // No match, check for varargs
+                    if (types[i].isArray() && i == types.length - 1) {
+                        // Try to parse the remaining arguments in an array
+                        Class<?> component = types[i].getComponentType();
+                        Object components = Array.newInstance(component, in
+                                .size()
+                                - i);
+                        int n = i;
+                        while (i < in.size()) {
+                            Object t = coerce(session, target, component, in
+                                    .get(i));
+                            if (t == NO_MATCH)
+                                return -1;
+                            Array.set(components, i - n, t);
+                            i++;
+                        }
+                        out[n] = components;
+                        // Is last element, so we will quite hereafter
+                        return n;
+                    }
+                    return -1;
+                }
+                i++;
+            } catch (Exception e) {
+                // e.printStackTrace();
+                System.err.println(e);
+                // should get rid of those exceptions, but requires
+                // reg ex matching to see if it throws an exception.
+                // dont know what is better
+                return -1;
+            }
+        }
+        return i;
+    }
+
+    Object coerce(CommandSession session, Object target, Class<?> type,
+            Object arg) throws Exception {
+        if (arg == null)
+            return null;
+
+        if (type.isAssignableFrom(arg.getClass()))
+            return arg;
+
+        Object converted = session.convert(type, arg);
+        if (converted != null)
+            return converted;
+
+        String string = arg.toString();
+        if (type.isAssignableFrom(String.class))
+            return string;
+
+        if (type.isArray()) {
+            // Must handle array types
+            return NO_MATCH;
+        } else if (!type.isPrimitive()) {
+            try {
+                return type.getConstructor(String.class).newInstance(string);
+            } catch (Exception e) {
+                return NO_MATCH;
+            }
+        }
+        if (type == boolean.class)
+            return new Boolean(string);
+        else if (type == byte.class)
+            return new Byte(string);
+        else if (type == char.class) {
+            if (string.length() == 1)
+                return string.charAt(0);
+        } else if (type == short.class)
+            return new Short(string);
+        else if (type == int.class)
+            return new Integer(string);
+        else if (type == float.class)
+            return new Float(string);
+        else if (type == double.class)
+            return new Double(string);
+        else if (type == long.class)
+            return new Long(string);
+
+        return NO_MATCH;
+    }
+
+    public static boolean hasCommand(Object target, String function) {
+        Method[] methods = target.getClass().getMethods();
+        for (Method m : methods) {
+            if (m.getName().equals(function))
+                return true;
+        }
+        return false;
+    }
+}
diff --git a/gogo/src/aQute/shell/stdio/StdioConsole.java b/gogo/src/aQute/shell/stdio/StdioConsole.java
new file mode 100644
index 0000000..d923996
--- /dev/null
+++ b/gogo/src/aQute/shell/stdio/StdioConsole.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package aQute.shell.stdio;
+
+import org.osgi.service.command.*;
+import org.osgi.service.component.*;
+
+import aQute.shell.console.*;
+
+public class StdioConsole extends Thread {
+    final Console console = new Console();
+
+    public StdioConsole() {
+        super("StdioConsole");
+    }
+    protected void activate(ComponentContext context) {
+        start();
+    }
+
+    protected void deactivate(ComponentContext context) {
+        console.close();
+        interrupt();
+    }
+
+    public void setProcessor(CommandProcessor processor ) {
+        console.setSession(processor.createSession(System.in,System.out,System.err));
+    }
+    
+    public void run() {
+        console.run();
+    }
+}
+
diff --git a/gogo/src/aQute/shell/telnet/Handler.java b/gogo/src/aQute/shell/telnet/Handler.java
new file mode 100644
index 0000000..e3791ea
--- /dev/null
+++ b/gogo/src/aQute/shell/telnet/Handler.java
@@ -0,0 +1,61 @@
+/*
+ * 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 aQute.shell.telnet;
+
+import java.io.*;
+import java.net.*;
+
+import org.osgi.service.command.*;
+
+import aQute.shell.console.*;
+
+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/src/aQute/shell/telnet/TelnetShell.java b/gogo/src/aQute/shell/telnet/TelnetShell.java
new file mode 100644
index 0000000..6e66de6
--- /dev/null
+++ b/gogo/src/aQute/shell/telnet/TelnetShell.java
@@ -0,0 +1,104 @@
+/*
+ * 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 aQute.shell.telnet;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import org.osgi.service.command.*;
+import org.osgi.service.component.*;
+
+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;
+    }
+}
